CF-558E (线段树/分块)
Posted blog-dr-j
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF-558E (线段树/分块)相关的知识,希望对你有一定的参考价值。
解题思路:
很显然突破口就是字符集比较小,分块和线段树都能A
话说线段树时间是分块5倍啊
代码(线段树):
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll spc<<1 5 #define rrr spc<<1|1 6 struct int_26{ 7 int has[30]; 8 void res(void) 9 { 10 memset(has,0,sizeof(has)); 11 return ; 12 } 13 int_26 friend operator + (int_26 x,int_26 y) 14 { 15 int_26 ans; 16 for(int i=1;i<=26;i++) 17 ans.has[i]=x.has[i]+y.has[i]; 18 return ans; 19 } 20 }isr; 21 struct trnt{ 22 int_26 val; 23 int lzt; 24 }tr[1000000]; 25 int n,q; 26 int ans[1000000]; 27 char cmd[1000000]; 28 void pushup(int spc) 29 { 30 tr[spc].val=tr[lll].val+tr[rrr].val; 31 return ; 32 } 33 void pushdown(int spc,int l,int r) 34 { 35 if(tr[spc].lzt) 36 { 37 int mid=(l+r)>>1; 38 tr[lll].lzt=tr[spc].lzt; 39 tr[rrr].lzt=tr[spc].lzt; 40 tr[spc].lzt=0; 41 tr[lll].val.res(); 42 tr[rrr].val.res(); 43 tr[lll].val.has[tr[lll].lzt]=mid-l+1; 44 tr[rrr].val.has[tr[rrr].lzt]=r-mid; 45 } 46 return ; 47 } 48 void build(int spc,int l,int r) 49 { 50 if(l==r) 51 { 52 tr[spc].val.has[cmd[l]-‘a‘+1]=1; 53 return ; 54 } 55 int mid=(l+r)>>1; 56 build(lll,l,mid); 57 build(rrr,mid+1,r); 58 pushup(spc); 59 return ; 60 } 61 void update(int l,int r,int ll,int rr,int spc,int v) 62 { 63 if(l>rr||ll>r) 64 return ; 65 if(ll<=l&&r<=rr) 66 { 67 tr[spc].val.res(); 68 tr[spc].val.has[v]=r-l+1; 69 tr[spc].lzt=v; 70 return ; 71 } 72 int mid=(l+r)>>1; 73 pushdown(spc,l,r); 74 update(l,mid,ll,rr,lll,v); 75 update(mid+1,r,ll,rr,rrr,v); 76 pushup(spc); 77 return ; 78 } 79 int_26 query(int l,int r,int ll,int rr,int spc) 80 { 81 if(l>rr||ll>r) 82 return isr; 83 if(ll<=l&&r<=rr) 84 return tr[spc].val; 85 int mid=(l+r)>>1; 86 pushdown(spc,l,r); 87 return query(l,mid,ll,rr,lll)+query(mid+1,r,ll,rr,rrr); 88 } 89 void S_pushdown(int l,int r,int spc) 90 { 91 if(l==r) 92 { 93 for(int i=1;i<=26;i++) 94 if(tr[spc].val.has[i]) 95 { 96 ans[l]=i; 97 break; 98 } 99 return ; 100 } 101 int mid=(l+r)>>1; 102 pushdown(spc,l,r); 103 S_pushdown(l,mid,lll); 104 S_pushdown(mid+1,r,rrr); 105 return ; 106 } 107 int main() 108 { 109 scanf("%d%d",&n,&q); 110 scanf("%s",cmd+1); 111 build(1,1,n); 112 while(q--) 113 { 114 int l,r,op; 115 scanf("%d%d%d",&l,&r,&op); 116 if(l>r) 117 std::swap(l,r); 118 int_26 tmp=query(1,n,l,r,1); 119 if(op) 120 { 121 int sta=l; 122 for(int i=1;i<=26;i++) 123 { 124 if(!tmp.has[i]) 125 continue; 126 update(1,n,sta,sta+tmp.has[i]-1,1,i); 127 sta+=tmp.has[i]; 128 } 129 }else{ 130 int sta=l; 131 for(int i=26;i;i--) 132 { 133 if(!tmp.has[i]) 134 continue; 135 update(1,n,sta,sta+tmp.has[i]-1,1,i); 136 sta+=tmp.has[i]; 137 } 138 } 139 } 140 S_pushdown(1,n,1); 141 for(int i=1;i<=n;i++) 142 printf("%c",ans[i]+‘a‘-1); 143 return 0; 144 }
代码(分块):
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 struct Area{ 6 int l,r; 7 int lzt;//1 shenx -1 jiangx 0 wu 8 int has[30]; 9 }p[200000]; 10 int n,q; 11 int a[200000]; 12 int blg[200000]; 13 int tmp[30]; 14 char cmd[1000000]; 15 bool cmp(int x,int y) 16 { 17 return x<y; 18 }//shenx 19 bool cmq(int x,int y) 20 { 21 return x>y; 22 }//jiangx 23 void P_sort(int x) 24 { 25 if(!p[x].lzt) 26 return ; 27 if(p[x].lzt==1) 28 { 29 int t=1; 30 for(int i=p[x].l;i<=p[x].r;i++) 31 { 32 while(!p[x].has[t]) 33 t++; 34 a[i]=t; 35 p[x].has[t]--; 36 } 37 } 38 if(p[x].lzt==-1) 39 { 40 int t=26; 41 for(int i=p[x].l;i<=p[x].r;i++) 42 { 43 while(!p[x].has[t]) 44 t--; 45 a[i]=t; 46 p[x].has[t]--; 47 } 48 } 49 p[x].lzt=0; 50 return ; 51 } 52 void build(int x) 53 { 54 for(int i=1;i<=26;i++) 55 p[x].has[i]=0; 56 for(int i=p[x].l;i<=p[x].r;i++) 57 p[x].has[a[i]]++; 58 return ; 59 } 60 int main() 61 { 62 scanf("%d%d",&n,&q); 63 if(n<=1000) 64 { 65 scanf("%s",cmd+1); 66 for(int i=1;i<=n;i++) 67 a[i]=cmd[i]-‘a‘+1; 68 for(int i=1;i<=q;i++) 69 { 70 int l,r,op; 71 scanf("%d%d%d",&l,&r,&op); 72 if(l>r) 73 std::swap(l,r); 74 if(op==0) 75 std::sort(a+l,a+r+1,cmq); 76 else 77 std::sort(a+l,a+r+1,cmp); 78 } 79 for(int i=1;i<=n;i++) 80 printf("%c",a[i]+‘a‘-1); 81 puts(""); 82 return 0; 83 } 84 scanf("%s",cmd+1); 85 int stan=(sqrt(n)); 86 for(int i=1;i<=n;i++) 87 { 88 a[i]=cmd[i]-‘a‘+1; 89 blg[i]=i/stan+1; 90 p[blg[i]].has[a[i]]++; 91 if(blg[i]!=blg[i-1]) 92 { 93 p[blg[i]].l=i; 94 p[blg[i-1]].r=i-1; 95 } 96 } 97 p[blg[n]].r=n; 98 while(q--) 99 { 100 int l,r,op; 101 scanf("%d%d%d",&l,&r,&op); 102 if(l>r) 103 std::swap(l,r); 104 if(blg[l]==blg[r]) 105 { 106 if(op==0) 107 std::sort(a+l,a+r+1,cmq); 108 else 109 std::sort(a+l,a+r+1,cmp); 110 continue; 111 } 112 memset(tmp,0,sizeof(tmp)); 113 P_sort(blg[l]); 114 build(blg[l]); 115 P_sort(blg[r]); 116 build(blg[r]); 117 for(int i=l;i<=p[blg[l]].r;i++) 118 tmp[a[i]]++; 119 for(int i=p[blg[r]].l;i<=r;i++) 120 tmp[a[i]]++; 121 for(int i=1;i<=26;i++) 122 for(int j=blg[l]+1;j<=blg[r]-1;j++) 123 tmp[i]+=p[j].has[i]; 124 if(op==0) 125 { 126 int t=26; 127 for(int i=l;i<=p[blg[l]].r;i++) 128 { 129 while(!tmp[t]) 130 t--; 131 tmp[t]--; 132 a[i]=t; 133 } 134 build(blg[l]); 135 for(int i=blg[l]+1;i<=blg[r]-1;i++) 136 { 137 int len=p[i].r-p[i].l+1; 138 for(int j=1;j<=26;j++) 139 p[i].has[j]=0; 140 while(tmp[t]<len) 141 { 142 p[i].has[t]+=tmp[t]; 143 len-=tmp[t]; 144 tmp[t]=0; 145 t--; 146 } 147 if(len) 148 { 149 p[i].has[t]+=len; 150 tmp[t]-=len; 151 if(!tmp[t]) 152 t--; 153 } 154 p[i].lzt=-1; 155 } 156 for(int i=p[blg[r]].l;i<=r;i++) 157 { 158 while(!tmp[t]) 159 t--; 160 tmp[t]--; 161 a[i]=t; 162 } 163 build(blg[r]); 164 }else{ 165 int t=1; 166 for(int i=l;i<=p[blg[l]].r;i++) 167 { 168 while(!tmp[t]) 169 t++; 170 tmp[t]--; 171 a[i]=t; 172 } 173 build(blg[l]); 174 for(int i=blg[l]+1;i<=blg[r]-1;i++) 175 { 176 int len=p[i].r-p[i].l+1; 177 for(int j=1;j<=26;j++) 178 p[i].has[j]=0; 179 while(tmp[t]<len) 180 { 181 p[i].has[t]+=tmp[t]; 182 len-=tmp[t]; 183 tmp[t]=0; 184 t++; 185 } 186 if(len) 187 { 188 p[i].has[t]+=len; 189 tmp[t]-=len; 190 if(!tmp[t]) 191 t++; 192 } 193 p[i].lzt=1; 194 } 195 for(int i=p[blg[r]].l;i<=r;i++) 196 { 197 while(!tmp[t]) 198 t++; 199 tmp[t]--; 200 a[i]=t; 201 } 202 build(blg[r]); 203 } 204 } 205 for(int i=1;i<=blg[n];i++) 206 P_sort(i); 207 for(int i=1;i<=n;i++) 208 printf("%c",a[i]+‘a‘-1); 209 puts(""); 210 return 0; 211 }
以上是关于CF-558E (线段树/分块)的主要内容,如果未能解决你的问题,请参考以下文章