【BZOJ】【P2329】【P2209】【HNOI2011】【括号修复】【题解】【Treap】

来源:互联网 发布:睫毛膏干了怎么办知乎 编辑:程序博客网 时间:2024/05/16 15:14

传送门: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();}elseif(op[0]=='Q'){res=*r;printf("%d\n",(res.maxr+1)/2-(res.minl-1)/2);}elseif(op[0]=='S'){r->makerev();r->pushdown();}elseif(op[0]=='I'){r->makelazy();r->pushdown();}root=merge(p,merge(r,s));}return 0;}


0 0
原创粉丝点击