题解:

splay打标机

往下传递

记录x,y为化简后,区间有多少(,)

代码:

#include<bits/stdc++.h>  
const int N=100005;  
using namespace std;  
int n,m,t,l,r,c[N][2],sum[N],a[N],sz[N],fa[N],rt,rev[N],ops[N];  
char s[N]; 
struct node
{ 
    int l0,l1,r0,r1;
}val[N];  
void maintain(int k)
{  
    int l=c[k][0],r=c[k][1];  
    sum[k]=a[k]+sum[l]+sum[r];sz[k]=sz[l]+sz[r]+1;  
    val[k].l0=min(val[l].l0,sum[l]+a[k]+val[r].l0);  
    val[k].l1=max(val[l].l1,sum[l]+a[k]+val[r].l1);  
    val[k].r0=min(val[r].r0,sum[r]+a[k]+val[l].r0);  
    val[k].r1=max(val[r].r1,sum[r]+a[k]+val[l].r1);  
}  
void rever(int k)
{  
    rev[k]^=1;
    swap(val[k].l0,val[k].r0);
    swap(val[k].l1,val[k].r1);  
}  
void opsite(int k)
{  
    ops[k]^=1;sum[k]=-sum[k];a[k]=-a[k];  
    swap(val[k].l0,val[k].l1);
    swap(val[k].r0,val[k].r1);  
    val[k].l0=-val[k].l0;val[k].l1=-val[k].l1;  
    val[k].r0=-val[k].r0;val[k].r1=-val[k].r1;  
}  
void pushdown(int k)
{  
    if (rev[k])
     {  
        swap(c[k][0],c[k][1]);rev[k]=0;  
        rever(c[k][0]);rever(c[k][1]);  
     }  
    if (ops[k])
     {  
        opsite(c[k][0]);
        opsite(c[k][1]);
        ops[k]=0;
     }  
}  
void rotate(int x,int &k)
{  
    int y=fa[x],z=fa[y],r=(x==c[y][0])?1:0;  
    if (y==k)k=x;
    else if (c[z][0]==y)c[z][0]=x; 
    else c[z][1]=x;  
    fa[x]=z;fa[y]=x;fa[c[x][r]]=y;  
    c[y][r^1]=c[x][r];c[x][r]=y;  
    maintain(y);maintain(x);  
}  
void splay(int x,int &k)
{  
    while (x!=k)
     {  
        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 find(int k,int rst)
{  
    pushdown(k);
    int l=c[k][0],r=c[k][1];  
    if (sz[l]+1==rst)return k;
    if (sz[l]>=rst)return find(l,rst);
    return find(r,rst-sz[l]-1);  
}  
void build(int &k,int l,int r,int last)
{  
    if (l>r)
     {
         k=0;
        return;
     }
    k=(l+r)>>1;
    fa[k]=last;  
    if (l==r)
     {  
        sum[k]=a[l];sz[k]=1;  
        if (a[l]<0)val[k].l0=val[k].r0=-1;
        if (a[l]>0)val[k].l1=val[k].r1=1;
        return;  
     }  
    build(c[k][0],l,k-1,k); 
    build(c[k][1],k+1,r,k); 
    maintain(k);  
}  
int main()
{  
    scanf("%d%d",&n,&m); 
    scanf("%s",s+2);  
    for (int i=2;i<=n+1;i++)  
     if (s[i]=='(')a[i]=1;else a[i]=-1;  
    build(rt,1,n+2,0);  
    while (m--)
     {   
        scanf("%d%d%d",&t,&l,&r);  
        l=find(rt,l);r=find(rt,r+2);  
        splay(l,rt);splay(r,c[l][1]);
        int k=c[r][0];
        if (t==0)printf("%d\n",(val[k].r1+1)/2-(val[k].l0-1)/2);  
        if (t==1)opsite(k);
        if (t==2)rever(k);
     }   
}  

 

posted on 2017-12-02 20:27  宣毅鸣  阅读(125)  评论(0编辑  收藏  举报