BZOJ2329: [HNOI2011]括号修复(Splay)

解题思路:

 Replace、Swap、Invert都可以使用Splay完美解决(只需要解决一下标记冲突就好了)。

最后只需要统计左右括号冲突就好了。

相当于动态统计最大前缀合和最小后缀和。

因为支持翻转反转操作,翻转标记或取反就好了。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define lll tr[spc].ch[0]
  5 #define rrr tr[spc].ch[1]
  6 #define ls ch[0]
  7 #define rs ch[1]
  8 typedef long long lnt;
  9 const int N=300000;
 10 struct trnt{
 11     int ch[2];
 12     int fa;
 13     int wgt;
 14     int val;
 15     int sum;
 16     int mxp;
 17     int mnp;
 18     int mxs;
 19     int mns;
 20     int lzt;
 21     bool rev;
 22     bool ant;
 23 }tr[N];
 24 int n,m;
 25 int siz;
 26 int root;
 27 int num[N];
 28 char cmd[N];
 29 bool whc(int spc)
 30 {
 31     return tr[tr[spc].fa].rs==spc;
 32 }
 33 void pushup(int spc)
 34 {
 35     tr[spc].wgt=1;
 36     if(lll)
 37         tr[spc].wgt+=tr[lll].wgt;
 38     if(rrr)
 39         tr[spc].wgt+=tr[rrr].wgt;
 40     tr[spc].sum=tr[spc].val;
 41     if(lll)
 42         tr[spc].sum+=tr[lll].sum;
 43     if(rrr)
 44         tr[spc].sum+=tr[rrr].sum;
 45     tr[spc].mxp=tr[spc].mxs=std::max(tr[spc].sum,0);
 46     tr[spc].mnp=tr[spc].mns=std::min(0,tr[spc].sum);
 47     if(lll)
 48     {
 49         tr[spc].mxp=std::max(tr[spc].mxp,std::max(tr[lll].mxp,tr[lll].sum+tr[spc].val));
 50         tr[spc].mnp=std::min(tr[spc].mnp,std::min(tr[lll].mnp,tr[lll].sum+tr[spc].val));
 51         tr[spc].mxs=std::max(tr[spc].mxs,std::max(tr[rrr].sum+tr[spc].val,tr[spc].val+tr[lll].mxs+tr[rrr].sum));
 52         tr[spc].mns=std::min(tr[spc].mns,std::min(tr[rrr].sum+tr[spc].val,tr[spc].val+tr[lll].mns+tr[rrr].sum));
 53     }
 54     if(rrr)
 55     {
 56         tr[spc].mxs=std::max(tr[spc].mxs,std::max(tr[rrr].mxs,tr[rrr].sum+tr[spc].val));
 57         tr[spc].mns=std::min(tr[spc].mns,std::min(tr[rrr].mns,tr[rrr].sum+tr[spc].val));
 58         tr[spc].mxp=std::max(tr[spc].mxp,std::max(tr[lll].sum+tr[spc].val,tr[spc].val+tr[lll].sum+tr[rrr].mxp));
 59         tr[spc].mnp=std::min(tr[spc].mnp,std::min(tr[lll].sum+tr[spc].val,tr[spc].val+tr[lll].sum+tr[rrr].mnp));
 60     }
 61     return ;
 62 }
 63 void trr(int spc)
 64 {
 65     if(!spc)
 66         return ;
 67     std::swap(lll,rrr);
 68     std::swap(tr[spc].mxp,tr[spc].mxs);
 69     std::swap(tr[spc].mnp,tr[spc].mns);
 70     tr[spc].rev^=1;
 71     return ;
 72 }
 73 void anti(int spc)
 74 {
 75     if(!spc)
 76         return ;
 77     tr[spc].val*=-1;
 78     tr[spc].sum*=-1;
 79     tr[spc].mxp*=-1;
 80     tr[spc].mnp*=-1;
 81     tr[spc].mxs*=-1;
 82     tr[spc].mns*=-1;
 83     std::swap(tr[spc].mxp,tr[spc].mnp);
 84     std::swap(tr[spc].mxs,tr[spc].mns);
 85     tr[spc].ant^=1;
 86     return ;
 87 }
 88 void chg(int spc,int v)
 89 {
 90     if(!spc)
 91         return ;
 92     tr[spc].ant=false;
 93     tr[spc].val=v;
 94     tr[spc].lzt=v;
 95     tr[spc].sum=v*tr[spc].wgt;
 96     if(v==1)
 97     {
 98         tr[spc].mnp=0;
 99         tr[spc].mns=0;
100         tr[spc].mxp=v*tr[spc].wgt;
101         tr[spc].mxs=v*tr[spc].wgt;
102     }else{
103         tr[spc].mxp=0;
104         tr[spc].mxs=0;
105         tr[spc].mnp=v*tr[spc].wgt;
106         tr[spc].mns=v*tr[spc].wgt;
107     }
108     return ;
109 }
110 void pushdown(int spc)
111 {
112     if(tr[spc].rev)
113     {
114         trr(lll);
115         trr(rrr);
116         tr[spc].rev=false;
117     }
118     if(tr[spc].lzt)
119     {
120         chg(lll,tr[spc].lzt);
121         chg(rrr,tr[spc].lzt);
122         tr[spc].lzt=0;
123     }
124     if(tr[spc].ant)
125     {
126         anti(lll);
127         anti(rrr);
128         tr[spc].ant=false;
129     }
130     return ;
131 }
132 void recal(int spc)
133 {
134     if(tr[spc].fa)
135         recal(tr[spc].fa);
136     pushdown(spc);
137     return ;
138 }
139 void rotate(int spc)
140 {
141     int f=tr[spc].fa;
142     bool k=whc(spc);
143     tr[f].ch[k]=tr[spc].ch[!k];
144     tr[spc].ch[!k]=f;
145     tr[tr[f].fa].ch[whc(f)]=spc;
146     tr[spc].fa=tr[f].fa;
147     tr[f].fa=spc;
148     tr[tr[f].ch[k]].fa=f;
149     pushup(f);
150     pushup(spc);
151     return ;
152 }
153 void splay(int spc,int f)
154 {
155     recal(spc);
156     while(tr[spc].fa!=f)
157     {
158         int ft=tr[spc].fa;
159         if(tr[ft].fa==f)
160         {
161             rotate(spc);
162             break;
163         }
164         if(whc(spc)^whc(ft))
165             rotate(spc);
166         else
167             rotate(ft);
168         rotate(spc);
169     }
170     if(!f)
171         root=spc;
172     return ;
173 }
174 void Build(int l,int r,int &spc,int f)
175 {
176     if(l>r)
177         return ;
178     int mid=(l+r)>>1;
179     spc=++siz;
180     tr[spc].val=num[mid];
181     tr[spc].fa=f;
182     Build(l,mid-1,lll,spc);
183     Build(mid+1,r,rrr,spc);
184     pushup(spc);
185     return ;
186 }
187 int plc(int spc,int k)
188 {
189     pushdown(spc);
190     if(tr[lll].wgt>=k)
191         return plc(lll,k);
192     if(tr[lll].wgt+1==k)
193         return spc;
194     return plc(rrr,k-tr[lll].wgt-1);
195 }
196 void rush(int l,int r)
197 {
198     l=plc(root,l);
199     r=plc(root,r+2);
200     splay(l,0);
201     splay(r,root);
202     return ;
203 }
204 int main()
205 {
206     scanf("%d%d",&n,&m);
207     scanf("%s",cmd+1);
208     for(int i=1;i<=n;i++)
209         num[i]=((cmd[i]==')')<<1)-1;
210     Build(0,n+1,root,0);
211     while(m--)
212     {
213         int l,r;
214         scanf("%s",cmd+1);
215         scanf("%d%d",&l,&r);
216         rush(l,r);
217         if(cmd[1]=='R')
218         {
219             scanf("%s",cmd+1);
220             chg(tr[tr[root].rs].ls,((cmd[1]==')')<<1)-1);
221         }else if(cmd[1]=='S')
222             trr(tr[tr[root].rs].ls);
223         else if(cmd[1]=='I')
224             anti(tr[tr[root].rs].ls);
225         else{
226             int spc=tr[tr[root].rs].ls;
227             printf("%d\n",(tr[spc].mxp+1)/2+(-tr[spc].mns+1)/2);
228         }
229         pushup(tr[root].rs);
230         pushup(root);
231     }
232     return 0;
233 }

猜你喜欢

转载自www.cnblogs.com/blog-Dr-J/p/10116235.html