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 }