1. 程式人生 > >CF-558E (線段樹/分塊)

CF-558E (線段樹/分塊)

!= ext through -s clu 分塊 mat line ora

解題思路:

很顯然突破口就是字符集比較小,分塊和線段樹都能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 (線段樹/分塊)