bzoj2209(splay)

来源:互联网 发布:韩国snow软件 编辑:程序博客网 时间:2024/05/01 00:52

debug很爽,表示细节错误一个有一个。

注意:1:在更新打标记时,要把原始数据和维护数据一起更新!!

2:在序列问题中,查找一个数只能用size找排名来找,因为,序列可能翻转!!

#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#include<algorithm>#include<stack>using namespace std;const int N=100005;int n,m,a[N];char s[N];int fa[N],ch[N][2],rev[N],fz[N],rt,mxl[N],mxr[N],mil[N],mir[N],sum[N],size[N];void up(int i){int l=ch[i][0],r=ch[i][1];size[i]=size[l]+size[r]+1;sum[i]=sum[l]+sum[r]+a[i];mxl[i]=max(0,max(sum[l]+a[i]+mxl[r],mxl[l]));mxr[i]=max(0,max(sum[r]+a[i]+mxr[l],mxr[r]));mil[i]=min(0,min(sum[l]+a[i]+mil[r],mil[l]));mir[i]=min(0,min(sum[r]+a[i]+mir[l],mir[r]));}int build(int fat,int l,int r){if (l>r) return 0;int mid=(l+r)>>1;fa[mid]=fat;size[mid]=1;ch[mid][0]=build(mid,l,mid-1);ch[mid][1]=build(mid,mid+1,r);up(mid);return mid;}void down(int i){int pos,l=ch[i][0],r=ch[i][1];if (fz[i]){fz[i]^=1,fz[l]^=1,fz[r]^=1;sum[l]=-sum[l],sum[r]=-sum[r];for (int j=0;j<=1;j++){pos=ch[i][j];a[pos]=-a[pos];swap(mxl[pos],mil[pos]);mxl[pos]=-mxl[pos];mil[pos]=-mil[pos];swap(mxr[pos],mir[pos]);mxr[pos]=-mxr[pos];mir[pos]=-mir[pos];}}if (rev[i]){rev[i]^=1,rev[l]^=1,rev[r]^=1;swap(ch[i][0],ch[i][1]);swap(mxl[l],mxr[l]);swap(mil[l],mir[l]);swap(mxl[r],mxr[r]);swap(mil[r],mir[r]);}}stack<int> ss;void rotate(int x)  {      int y=fa[x],z=fa[y],l,r;      if (ch[y][0]==x) l=0;else l=1;r=l^1;      if (z) if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;      fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;      ch[y][l]=ch[x][r];ch[x][r]=y; up(y); }  void splay(int x,int k)  {      int y,z;      while (fa[x]!=k)      {          y=fa[x];z=fa[y];          if (z!=k)          {              if ((ch[z][0]==y)^(ch[y][0]==x)) rotate(x);else rotate(y);          }          rotate(x);      }      if (k==0) rt=x;up(x); }  int find_kth(int u,int k)//必须用名次查找位置!!!{down(u);if (size[ch[u][0]]+1==k) return u;if (size[ch[u][0]]>=k) return find_kth(ch[u][0],k);return find_kth(ch[u][1],k-size[ch[u][0]]-1);}int split(int x,int y){int posx=find_kth(rt,x-1);splay(posx,0);int posy=find_kth(rt,y+1);splay(posy,posx);return ch[posy][0];}inline int read(){int ans;char ch;while ((ch=getchar())<'0'||ch>'9');ans=ch-'0';while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0';return ans;}int main(){n=read(),m=read();scanf("%s",s+1);for (int i=2;i<=n+1;i++) if (s[i-1]=='(') a[i]=1;else a[i]=-1;a[1]=a[n+2]=0;rt=build(0,1,n+2);int t,x,y,pos;for (int i=1;i<=m;i++){t=read(),x=read(),y=read();x++,y++;pos=split(x,y);switch(t){case 0:printf("%d\n",-(mil[pos]-1)/2+(mxr[pos]+1)/2);break;case 1:fz[pos]^=1;a[pos]=-a[pos];//注意把原始数据更新!!查了好长时间sum[pos]=-sum[pos];swap(mxl[pos],mil[pos]);mxl[pos]=-mxl[pos];mil[pos]=-mil[pos];swap(mxr[pos],mir[pos]);mxr[pos]=-mxr[pos];mir[pos]=-mir[pos];up(fa[pos]);up(rt);break;case 2:rev[pos]^=1;swap(mxl[pos],mxr[pos]);swap(mil[pos],mir[pos]);up(fa[pos]),up(rt);break;}}return 0;}


 

0 0