传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2329 http://www.lydsy.com/JudgeOnline/problem.php?id=2209
同【Jsoi2011】【括号序列】
双倍经验
把(当成1 ,)当成-1
那么维护左右的最大/小连续和
fhqTreap写多了感觉还是挺好写的……就是比普通Splay慢……
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cctype>
#include<climits>
using namespace std;
const int maxn=1e5+5;
int n,m;
char str[maxn];
inline int rnd(){
static int KEY=12345678;
return KEY+=KEY<<2|1;
}
struct node{
int val,key,rev,lazy,all,maxl,minl,maxr,minr,size,sum;node *c[2];
node(int _val=0,node *C=0):
val(_val),key(rnd()),rev(0),lazy(0),all(0),maxl(0),minl(0),maxr(0),minr(0),size(1),sum(_val){c[0]=c[1]=C;}
node *rz(){
size=c[0]->size+1+c[1]->size;
sum=c[0]->sum+val+c[1]->sum;
maxl=max(c[0]->maxl,c[0]->sum+val+max(0,c[1]->maxl));
minl=min(c[0]->minl,c[0]->sum+val+min(0,c[1]->minl));
maxr=max(c[1]->maxr,c[1]->sum+val+max(0,c[0]->maxr));
minr=min(c[1]->minr,c[1]->sum+val+min(0,c[0]->minr));
return this;
}
void makerev(){
if(this->size==0)return;
rev^=1;
swap(c[0],c[1]);
swap(minl,minr);
swap(maxl,maxr);
}
void makelazy(){
if(this->size==0)return;
lazy^=1;
if(all)
all=-all;
val=-val;
sum=-sum;
swap(maxl,minl);maxl=-maxl;minl=-minl;
swap(maxr,minr);maxr=-maxr;minr=-minr;
}
void makesame(int al){
if(this->size==0)return;
all=al;val=al;
maxl=maxr=size*(al==1);
minl=minr=-size*(al==-1);
sum=size*al;
}
void pushdown(){
if(this->size==0)return;
if(rev){c[0]->makerev();c[1]->makerev();rev^=1;}
if(lazy){c[0]->makelazy();c[1]->makelazy();lazy=0;}
if(all){c[0]->makesame(all);c[1]->makesame(all);all=0;}
}
void split(int ned,node *&p,node *&q);
}*Null;
node *merge(node *p,node *q){
p->pushdown();q->pushdown();
if(p==Null)return q->rz();
if(q==Null)return p->rz();
if(p->key<q->key){
p->c[1]=merge(p->c[1],q);
return p->rz();
}else{
q->c[0]=merge(p,q->c[0]);
return q->rz();
}
}
void node::split(int ned,node *&p,node *&q){
if(this==Null){p=q=Null;return;}
pushdown();
if(c[0]->size>=ned){
c[0]->split(ned,p,q);
c[0]=Null;rz();
q=merge(q,this);
}else{
c[1]->split(ned-c[0]->size-1,p,q);
c[1]=Null;rz();
p=merge(this,p);
}
}
node *root;
node *newnode(int val=0){
return new node(val,Null);
}
node *p,*q,*r,*s,res;
void deb(node *root){
if(root==Null)return ;
printf("val:%d sum:%d size:%d all:%d rev:%d lazy:%d \n",root->val,root->sum,root->size,
root->all,root->rev,root->lazy);
if(root->c[0]!=Null)printf("L:"),deb(root->c[0]);
if(root->c[1]!=Null)printf("R:"),deb(root->c[1]);
}
int main(){
Null=newnode();Null->size=0;
Null->val=Null->key=INT_MAX;
root=Null;
scanf("%d%d",&n,&m);
scanf("%s",str);
for(int i=0;i<n;i++)root=merge(root,newnode(str[i]=='('?1:-1));
while(m--){
char op[10];
int lef,rig;
scanf("%s%d%d",op,&lef,&rig);
root->split(lef-1,p,q);
q->split(rig-lef+1,r,s);
if(op[0]=='R'){
char x=getchar();while(x!='('&&x!=')')x=getchar();
r->makesame(x=='('?1:-1);
r->pushdown();
}else
if(op[0]=='Q'){
res=*r;
printf("%d\n",(res.maxr+1)/2-(res.minl-1)/2);
}else
if(op[0]=='S'){
r->makerev();
r->pushdown();
}else
if(op[0]=='I'){
r->makelazy();
r->pushdown();
}
root=merge(p,merge(r,s));
}
return 0;
}