题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2329
题意:
思路:此题除了Replace操作外与BZOJ2209一样。那么多了一个Replace操作,要注意,这个操作与Invert操作有先后之分。若Replace早于Invert发生,那么在Invert操作发生时要将Replace的标记取反,这样pushDown时先Invert再Replace;若Replace晚于Invert,则Invert操作可以忽略。
struct node
{
int op1,op2,op3,val,LMin,LMax,RMin,RMax,sum;
int size;
node *c[2],*p;
void invert()
{
val*=-1; sum*=-1;
int temp;
temp=LMin; LMin=-LMax; LMax=-temp;
temp=RMin; RMin=-RMax; RMax=-temp;
op1^=1;
if(op3) op3*=-1;
}
void turnover()
{
swap(LMin,RMin);
swap(LMax,RMax);
swap(c[0],c[1]);
op2^=1;
}
void replace(int x)
{
op1=0;
op3=x;
val=x;
if(x==1)
{
sum=size;
LMin=0; LMax=size;
RMin=0; RMax=size;
}
else
{
sum=-size;
LMin=-size; LMax=0;
RMin=-size; RMax=0;
}
}
};
node a[N],*root,*nullNode;
int cnt;
void pushUp(node *p)
{
if(p==nullNode) return;
p->size=1+p->c[0]->size+p->c[1]->size;
p->sum=p->c[0]->sum+p->val+p->c[1]->sum;
p->LMin=p->c[0]->LMin;
p->LMin=min(p->LMin,p->c[0]->sum+p->val);
p->LMin=min(p->LMin,p->c[0]->sum+p->val+p->c[1]->LMin);
p->LMax=p->c[0]->LMax;
p->LMax=max(p->LMax,p->c[0]->sum+p->val);
p->LMax=max(p->LMax,p->c[0]->sum+p->val+p->c[1]->LMax);
p->RMin=p->c[1]->RMin;
p->RMin=min(p->RMin,p->c[1]->sum+p->val);
p->RMin=min(p->RMin,p->c[1]->sum+p->val+p->c[0]->RMin);
p->RMax=p->c[1]->RMax;
p->RMax=max(p->RMax,p->c[1]->sum+p->val);
p->RMax=max(p->RMax,p->c[1]->sum+p->val+p->c[0]->RMax);
}
int ok(node *p)
{
return p!=nullNode&&(p!=&a[1])&&(p!=&a[2]);
}
void pushDown(node *p)
{
if(p==nullNode) return;
if(p->op1)
{
if(ok(p->c[0])) p->c[0]->invert();
if(ok(p->c[1])) p->c[1]->invert();
p->op1=0;
}
if(p->op2)
{
if(ok(p->c[0])) p->c[0]->turnover();
if(ok(p->c[1])) p->c[1]->turnover();
p->op2=0;
}
if(p->op3)
{
if(ok(p->c[0])) p->c[0]->replace(p->op3);
if(ok(p->c[1])) p->c[1]->replace(p->op3);
p->op3=0;
}
}
node *newNode(int val,node *p)
{
node *e=&a[cnt++];
e->c[0]=e->c[1]=nullNode;
e->p=p;
e->op1=e->op2=e->op3=0;
e->size=1;
e->sum=e->val=e->LMin=e->RMin=e->LMax=e->RMax=val;
return e;
}
void init()
{
nullNode=0;
nullNode=newNode(0,nullNode);
nullNode->size=0;
nullNode->LMin=nullNode->RMin=INF;
nullNode->LMax=nullNode->RMax=-INF;
nullNode->sum=0;
root=newNode(0,nullNode);
root->LMin=root->RMin=INF;
root->LMax=root->RMax=-INF;
root->sum=0;
root->c[1]=newNode(0,root);
root->c[1]->LMin=root->c[1]->RMin=INF;
root->c[1]->LMax=root->c[1]->RMax=-INF;
root->c[1]->sum=0;
pushUp(root);
}
void zig(node *x)
{
node *p=x->p,*q=p->p;
p->c[0]=x->c[1];
if(x->c[1]!=nullNode) x->c[1]->p=p;
x->c[1]=p;
p->p=x;
x->p=q;
if(q!=nullNode)
{
if(q->c[0]==p) q->c[0]=x;
else q->c[1]=x;
}
pushUp(p);
pushUp(x);
if(root==p) root=x;
}
void zag(node *x)
{
node *p=x->p,*q=p->p;
p->c[1]=x->c[0];
if(x->c[0]!=nullNode) x->c[0]->p=p;
x->c[0]=p;
p->p=x;
x->p=q;
if(q!=nullNode)
{
if(q->c[0]==p) q->c[0]=x;
else q->c[1]=x;
}
pushUp(p);
pushUp(x);
if(root==p) root=x;
}
void splay(node *x,node *goal)
{
while(x->p!=goal)
{
if(x->p->p!=goal)
{
pushDown(x->p->p);
pushDown(x->p);
pushDown(x);
if(x->p->p->c[0]==x->p)
{
if(x->p->c[0]==x) zig(x->p),zig(x);
else zag(x),zig(x);
}
else
{
if(x->p->c[1]==x) zag(x->p),zag(x);
else zig(x),zag(x);
}
}
else
{
pushDown(x->p);
pushDown(x);
if(x->p->c[0]==x) zig(x);
else zag(x);
}
}
}
void select(int k,node *goal)
{
node *p=root;
pushDown(p);
while(k!=p->c[0]->size+1)
{
if(k<=p->c[0]->size) p=p->c[0];
else
{
k-=1+p->c[0]->size;
p=p->c[1];
}
pushDown(p);
}
splay(p,goal);
}
node *build(int L,int R,char str[],node *p)
{
if(L>R) return nullNode;
int mid=(L+R)>>1;
node *e=newNode(str[mid]=='('?1:-1,p);
e->c[0]=build(L,mid-1,str,e);
e->c[1]=build(mid+1,R,str,e);
pushUp(e);
return e;
}
void insert(int p,int n,char str[])
{
select(p+1,nullNode);
select(p+2,root);
node *e=build(1,n,str,root->c[1]);
root->c[1]->c[0]=e;
splay(e,nullNode);
}
int query(int L,int R)
{
select(L,nullNode);
select(R+2,root);
node *p=root->c[1]->c[0];
return -(p->LMin-1)/2+(p->RMax+1)/2;
}
void invert(int L,int R)
{
select(L,nullNode);
select(R+2,root);
node *p=root->c[1]->c[0];
p->invert();
splay(p,nullNode);
}
void rep(int L,int R,int x)
{
select(L,nullNode);
select(R+2,root);
node *p=root->c[1]->c[0];
p->replace(x);
splay(p,nullNode);
}
void turnover(int L,int R)
{
select(L,nullNode);
select(R+2,root);
node *p=root->c[1]->c[0];
p->turnover();
splay(p,nullNode);
}
int n,m;
char str[N];
int main()
{
init(); RD(n,m); RD(str+1); insert(0,n,str);
int x,y;
char op[10],S[10];
while(m--)
{
RD(op);RD(x,y);
if(strcmp(op,"Query")==0) PR(query(x,y));
else if(strcmp(op,"Invert")==0) invert(x,y);
else if(strcmp(op,"Swap")==0) turnover(x,y);
else if(strcmp(op,"Replace")==0) RD(S),rep(x,y,S[0]=='('?1:-1);
}
}