HZOJ string
生活随笔
收集整理的這篇文章主要介紹了
HZOJ string
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正解炸了……
考試的時候想到了正解,非常高興的打出來了線段樹,又調了好長時間,對拍了一下發現除了非常大的點跑的有點慢外其他還行。因為復雜度算著有點高……
最后正解死于常數太大……旁邊的lyl用同樣的算法拿了90分我卻拿了個暴力的分40……花了那么多時間一分沒多拿原地爆炸……
由于大部分時間押在了T1,然后考試就炸了……
題解:
因為字符串長度雖然很大,但是只有26個字符,考慮桶排,用線段樹每個節點開一個26的桶,維護這個區間中各個數的個數,對于排序就可以拆成26次區間賦值。然而這樣的down函數的復雜度是26,于是整個算法的復雜度就成了$nlog_n*26^2$,40分成功炸掉(加兩個優化可以搞到60分),然后就有lyl及其沒有素質地給他循環展開了,AC……
還是說正解吧,和‘花神游歷各國’類似,線段樹維護這一段的值,不一樣則為0,本來以為這樣會很慢,但是它會越來越快:每次排序最多增加2個塊,但這種增加是有限制的,大部分情況下塊是在減少,所以它會越來越快。由于此時的down是O1的,于是總復雜度$nlog_n*26$,成功A掉。
?
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define MAXN 100010 5 using namespace std; 6 struct tree 7 { 8 int l,r,sum; 9 #define l(x) tr[x].l 10 #define r(x) tr[x].r 11 #define ls(x) (x*2) 12 #define rs(x) ((ls(x))+1) 13 #define sum(x) tr[x].sum 14 }tr[MAXN*100]; 15 char a[MAXN]; 16 int n,m,yz[MAXN]; 17 void pushup(int x) 18 { 19 if(l(x)==r(x))return; 20 sum(x)=(sum(ls(x))==sum(rs(x))?sum(ls(x)):0); 21 } 22 void build(int l,int r,int x) 23 { 24 l(x)=l,r(x)=r; 25 if(l==r){sum(x)=a[l];yz[l]=x;return;} 26 int mid=(l+r)>>1; 27 build(l,mid,ls(x)); 28 build(mid+1,r,rs(x)); 29 pushup(x); 30 } 31 void down(int x) 32 { 33 if(!sum(x))return; 34 if(l(x)!=r(x))sum(ls(x))=sum(rs(x))=sum(x); 35 } 36 void add(int l,int r,int x,int data) 37 { 38 if((l(x)>=l&&r(x)<=r)||sum(x)==data) 39 {sum(x)=data;down(x);return;} 40 down(x); 41 int mid=(l(x)+r(x))>>1; 42 if(l<=mid)add(l,r,ls(x),data); 43 if(r>mid) add(l,r,rs(x),data); 44 pushup(x); 45 } 46 int t[27]; 47 void ask(int l,int r,int x) 48 { 49 down(x); 50 if(l>r(x)||r<l(x))return; 51 if(l<=l(x)&&r>=r(x)&&sum(x)) 52 { 53 t[sum(x)]+=r(x)-l(x)+1; 54 return; 55 } 56 down(x); 57 int mid=(l(x)+r(x))>>1; 58 if(l<=mid)ask(l,r,ls(x)); 59 if(r>mid) ask(l,r,rs(x)); 60 } 61 void work(int x,int l,int r) 62 { 63 memset(t,0,sizeof(t)); 64 ask(l,r,1); 65 int tl=l; 66 if(x==1) 67 { 68 for(register int i=1;i<=26;i++) 69 if(t[i]) 70 { 71 add(tl,tl+t[i]-1,1,i); 72 tl=tl+t[i]; 73 } 74 } 75 else 76 { 77 for(register int i=26;i>=1;i--) 78 if(t[i]) 79 { 80 add(tl,tl+t[i]-1,1,i); 81 tl=tl+t[i]; 82 } 83 } 84 } 85 void dfs(int x) 86 { 87 down(x); 88 if(l(x)==r(x))return; 89 dfs(ls(x)),dfs(rs(x)); 90 } 91 inline int read(); 92 signed main() 93 { 94 // freopen("in.txt","r",stdin) ; 95 96 n=read(),m=read(); 97 char ooo=getchar();int len=0; 98 while(ooo<'a'||ooo>'z')ooo=getchar(); 99 while(ooo>='a'&&ooo<='z'){a[++len]=ooo-'a'+1;ooo=getchar();} 100 build(1,n,1); 101 int x,l,r; 102 for(register int i=1;i<=m;++i) 103 { 104 l=read(),r=read(),x=read(); 105 work(x,l,r); 106 } 107 dfs(1); 108 for(int i=1;i<=n;i++) 109 putchar(sum(yz[i])+'a'-1); 110 puts(""); 111 } 112 inline int read() 113 { 114 int s=0;char a=getchar(); 115 while(a<'0'||a>'9')a=getchar(); 116 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();} 117 return s; 118 } View Code?
轉載于:https://www.cnblogs.com/Al-Ca/p/11286365.html
總結
以上是生活随笔為你收集整理的HZOJ string的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同步阻塞处理的几种方法
- 下一篇: git仓库如果是私密的,每台电脑上导下来