bzoj2209: [Jsoi2011]括号序列

来源:互联网 发布:免费的微信多开软件 编辑:程序博客网 时间:2024/05/21 19:36

还是个splay模板,写了一个晚上…太菜了

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int read(){    char ch=getchar();int f=0,x=1;    while(ch<'0'||ch>'9'){if(ch=='-') x=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){f=(f<<1)+(f<<3)+ch-'0';ch=getchar();}    return f*x;}int n,m,fa[100005],c[100005][2],cnt,key[100005],rt;bool rev[100005],neg[100005];char s[100005];int pos[100005],prex[100005],sufx[100005],pren[100005],sufn[100005];int size[100005],sum[100005];void update(int now){    prex[0]=sufx[0]=-1000000000;     pren[0]=sufn[0]=1000000000; key[0]=0;    //key[1]=0;    int l=c[now][0],r=c[now][1];    size[now]=size[l]+size[r]+1;    sum[now]=sum[l]+sum[r]+key[now];    int lenp=max(sum[l]+key[now],sum[l]+prex[r]+key[now]);    prex[now]=max(lenp,prex[l]);    lenp=min(sum[l]+key[now],sum[l]+pren[r]+key[now]);    pren[now]=min(lenp,pren[l]);    int lens=max(sum[r]+key[now],sum[r]+sufx[l]+key[now]);    sufx[now]=max(lens,sufx[r]);    lens=min(sum[r]+key[now],sum[r]+sufn[l]+key[now]);    sufn[now]=min(lens,sufn[r]);    //cout<<prex[now]<<" "<<pren[now]<<" "<<sufx[now]<<" "<<sufn[now]<<" "<<sum[now]<<endl;}void change(int now){    swap(prex[now],sufx[now]);    swap(pren[now],sufn[now]);}void change1(int now){    sum[now]=-sum[now];    key[now]=-key[now];    prex[now]=-prex[now];sufx[now]=-sufx[now];    pren[now]=-pren[now];sufn[now]=-sufn[now];    swap(prex[now],pren[now]);    swap(sufn[now],sufx[now]);}void pushdown(int x){    if(rev[x])    {        change(c[x][0]);change(c[x][1]);        swap(c[x][0],c[x][1]);        rev[c[x][0]]^=1;rev[c[x][1]]^=1;        rev[x]=0;    }    if(neg[x])    {        change1(c[x][0]);change1(c[x][1]);        neg[c[x][0]]^=1;neg[c[x][1]]^=1;        neg[x]=0;    }}void rotate(int x,int &k){    int y=fa[x],z=fa[y],l,r;    //cout<<x<<" "<<y<<" "<<k<<endl;    pushdown(y);pushdown(x);    if(c[y][1]==x) l=1;else l=0;r=l^1;    if(y==k) k=x;    else    {        if(c[z][0]==y) c[z][0]=x;else c[z][1]=x;    }    fa[y]=x;fa[x]=z;fa[c[x][r]]=y;    c[y][l]=c[x][r];c[x][r]=y;    update(y);update(x);}void splay(int x,int &k){    while(x!=k)    {        //cout<<x<<" "<<k<<endl;        int y=fa[x],z=fa[y];        if(y!=k)        {            if(c[y][0]==x^c[z][0]==y) rotate(x,k);            else rotate(y,k);        }        rotate(x,k);    }}int build(int l,int r,int p){    if(l>r) return 0;    int mid=l+r>>1;int now=++cnt;    key[now]=pos[mid];fa[now]=p;    c[now][0]=build(l,mid-1,now);    c[now][1]=build(mid+1,r,now);    update(now);        //cout<<l<<" "<<r<<" "<<now<<"!"<<endl;    //cout<<prex[now]<<" "<<pren[now]<<" "<<sufx[now]<<" "<<sufn[now]<<" "<<sum[now]<<endl;    return now;}int find(int x){    int now=rt;    while(1)    {        pushdown(now);        if(x<=size[c[now][0]])        now=c[now][0];        else        {            int ans=size[c[now][0]]+1;            if(ans==x) return now;            x-=ans;now=c[now][1];        }    }}int main(){    n=read();m=read();    scanf("%s",s+1);    for(int i=1;i<=n;i++)    if(s[i]=='(') pos[i]=-1;else pos[i]=1;    rt=build(0,n+1,0);    //for(int j=1;j<=n+1;j++) cout<<prex[j]<<" "<<sufx[j]<<" "<<sufn[j]<<" "<<pren[j]<<endl;    for(int i=1;i<=m;i++)    {        int op=read(),x=read(),y=read();        int l=find(x),r=find(y+2);        splay(l,rt);splay(r,c[l][1]);        int t=c[c[rt][1]][0];//cout<<t<<endl;        //for(int j=0;j<=n+1;j++) cout<<prex[j]<<" "<<sufx[j]<<" "<<sufn[j]<<" "<<pren[j]<<endl;        if(op==0)        {            int ans=prex[t],ans1=sufn[t];            if(ans1>0) ans1=0;            else ans1=-ans1;            if(ans<0) ans=0;            //cout<<ans<<" "<<ans1<<endl;            if(ans&1||ans1&1) printf("%d\n",(ans+ans1>>1)+1);            else printf("%d\n",ans+ans1>>1);        }        if(op==1)        {            neg[t]^=1;            change1(t);            update(c[rt][1]);update(rt);        }        if(op==2)        {            rev[t]^=1;            change(t);update(c[rt][1]);update(rt);        }    }}
原创粉丝点击