bzoj2329: [HNOI2011]括号修复
觉得自底向上的splay贼神奇我竟然天真地写了自底向上,就不用kth了啊直接找到多好,然后发现我怕是个zz,我一reverse序号早乱了。。。
所以不能自底向上,至少我认为那是没有意义的。
然后就是取反的时候也是取异或,每次都会忘了这点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=200010;
typedef long long LL;
using namespace std;
int rt,n,m,tot;
char s[N],o[10];
template<typename T>void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int p[N],ch[N][2],v[N],flip[N],op[N],cover[N],sum[N],lmi[N],lmx[N],rmx[N],rmi[N],sz[N];
#define lc ch[x][0]
#define rc ch[x][1]
void update(int x) {
sum[x]=sum[lc]+sum[rc]+v[x];
sz[x]=sz[lc]+sz[rc]+1;
lmi[x]=min(lmi[lc],sum[lc]+v[x]+lmi[rc]);
lmx[x]=max(lmx[lc],sum[lc]+v[x]+lmx[rc]);
rmi[x]=min(rmi[rc],sum[rc]+v[x]+rmi[lc]);
rmx[x]=max(rmx[rc],sum[rc]+v[x]+rmx[lc]);
}
void cover_it(int x,int w) {
sum[x]=sz[x]*w; v[x]=w;
cover[x]=w; flip[x]=op[x]=0;
lmi[x]=rmi[x]=min(0,sz[x]*w);
lmx[x]=rmx[x]=max(0,sz[x]*w);
}
void get_oppo(int x) {
swap(lmi[x],lmx[x]);
swap(rmi[x],rmx[x]);
if(cover[x]) cover[x]*=-1; else op[x]^=1; //取反也是异或!
sum[x]*=-1,v[x]*=-1;
lmi[x]*=-1,lmx[x]*=-1;
rmi[x]*=-1,rmx[x]*=-1;
}
void reverse(int x) {
swap(lc,rc);
swap(lmi[x],rmi[x]);
swap(lmx[x],rmx[x]);
flip[x]^=1;
}
void down(int x) {
if(!cover[x]&&!op[x]&&!flip[x]) return;
if(cover[x]) {
if(lc) cover_it(lc,cover[x]);
if(rc) cover_it(rc,cover[x]);
}
if(op[x]) {
if(lc) get_oppo(lc);
if(rc) get_oppo(rc);
}
if(flip[x]) {
if(lc) reverse(lc);
if(rc) reverse(rc);
}
cover[x]=op[x]=flip[x]=0;
}
void rotate(int x) {
int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
if(z) ch[z][y==ch[z][1]]=x; p[x]=z;
ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
ch[x][r]=y; p[y]=x;
update(y); update(x);
}
void splay(int x,int FA) {
/*static int g[N],top=0,tp;
for(tp=x;tp!=FA;tp=p[tp]) g[++top]=tp;
g[++top]=tp;
while(top) down(g[top--]);*/ //不能自底向上!
for(;p[x]!=FA;rotate(x)) {
int y=p[x],z=p[y];
if(z!=FA) ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
}
if(!FA) rt=x;
}
int build(int sz) {
if(!sz) return 0;
int ls,rs,x;
ls=build(sz>>1);
x=++tot;
rs=build(sz-(sz>>1)-1);
if(ls) p[ls]=x; lc=ls;
if(rs) p[rs]=x; rc=rs;
update(x);
return x;
}
int kth(int k) {
for(int x=rt;x;) {
down(x);
if(sz[lc]+1==k) return x;
if(sz[lc]+1<k) k-=(sz[lc]+1),x=rc;
else x=lc;
} return -1;
}
int get_it(int l,int r) {
l=kth(l); r=kth(r+2);
splay(l,0); splay(r,l);
return ch[r][0];
}
int main() {
#ifdef DEBUG
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
read(n); read(m);
scanf("%s",s+1);
for(int i=1;i<=n;i++) v[i+1]=(s[i]=='(')?-1:1;
/*ch[n+1][1]=n+2; p[n+2]=n+1;
ch[n+2][0]=build(n); p[ch[n+2][0]]=n+2;
update(n+2); update(n+1); rt=n+1;*/
rt=build(n+2);
while(m--) {
scanf("%s",o);
int l,r,w;
read(l); read(r);
int x=get_it(l,r);
if(o[0]=='R') {
scanf("%s",o);
w=(o[0]=='(')?-1:1;
cover_it(x,w);
}
else if(o[0]=='S') reverse(x);
else if(o[0]=='I') get_oppo(x);
else if(o[0]=='Q') {
int ans=(lmx[x]+1)/2+(-rmi[x]+1)/2; //// no lmi rmx
printf("%d\n",ans);
}
update(p[x]); update(p[p[x]]);
}
return 0;
}
/*
4 4
((((
Replace 1 2 )
Swap 2 3
Invert 3 4
Query 1 4
4 3
((((
Swap 2 4
Swap 3 4
Query 1 4
*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<ctime>
using namespace std;
#define ll long long
#define db double
int n=40,m=50;
char cc; ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
}
int main() {
srand((unsigned)time(NULL));
printf("%d %d\n",n,m);
for(int i=1;i<=n;i++) {
int o=rand()%2;
if(o==1) printf("(");
else printf(")");
} puts("");
for(int i=1;i<=m;i++) {
int o=rand()%4;
int l=rand()%n+1,r=rand()%n+1;
if(l>r) swap(l,r);
if(o==1) {
printf("Replace ");
printf("%d %d ",l,r);
o=rand()%2;
if(o==1) printf("(");
else printf(")");
}
else if(o==2) {
printf("Query ");
printf("%d %d ",l,r);
}
else if(o==3) {
printf("Swap ");
printf("%d %d ",l,r);
}
else {
printf("Invert ");
printf("%d %d ",l,r);
}
puts("");
}
return 0;
}