• ●BZOJ 2329 [HNOI2011]括号修复.cpp


    题链:

    Splay
    类似 BZOJ 2329 [HNOI2011]括号修复
    只是多了一个Replace(替换)操作,
    然后就要主要lazy标记之间的影响了。
    1).Replace可以直接覆盖另外两个标记,
    2).当已经有Replace标记,再覆盖Invert标记时,直接把Replace标记取反即可;在覆盖Swap标记时,Replace标记不变。
    代码:
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXN 100500
    using namespace std;
    char s[10];
    int N,M;
    struct SPT{
    	int pmx[MAXN],pmn[MAXN],smx[MAXN],smn[MAXN],sum[MAXN],key[MAXN];
    	int ch[MAXN][2],siz[MAXN],fa[MAXN],cg[MAXN],lazy[MAXN],rt;
    	void Invert(int x){
    		sum[x]*=-1; key[x]*=-1;
    		pmx[x]*=-1; pmn[x]*=-1; swap(pmx[x],pmn[x]);
    		smx[x]*=-1; smn[x]*=-1; swap(smx[x],smn[x]);
    	}
    	void Swap(int x){
    		swap(pmx[x],smx[x]);
    		swap(pmn[x],smn[x]);
    		swap(ch[x][0],ch[x][1]);
    	}
    	void Replace(int x,int c){
    		key[x]=c; sum[x]=c*siz[x];
    		pmx[x]=max(sum[x],0); pmn[x]=min(sum[x],0);
    		smx[x]=max(sum[x],0); smn[x]=min(sum[x],0);
    	}
    	void Pushup(int x){
    		siz[x]=siz[ch[x][0]]+1+siz[ch[x][1]];
    		sum[x]=sum[ch[x][0]]+key[x]+sum[ch[x][1]];
    		pmx[x]=max(pmx[ch[x][0]],sum[ch[x][0]]+key[x]+pmx[ch[x][1]]);
    		pmn[x]=min(pmn[ch[x][0]],sum[ch[x][0]]+key[x]+pmn[ch[x][1]]); 
    		smx[x]=max(smx[ch[x][1]],sum[ch[x][1]]+key[x]+smx[ch[x][0]]);
    		smn[x]=min(smn[ch[x][1]],sum[ch[x][1]]+key[x]+smn[ch[x][0]]);
    	}
    	void Pushdown(int x){
    		if(cg[x]!=0){
    			Replace(ch[x][0],cg[x]); cg[ch[x][0]]=cg[x]; lazy[ch[x][0]]=0;
    			Replace(ch[x][1],cg[x]); cg[ch[x][1]]=cg[x]; lazy[ch[x][1]]=0;
    			cg[x]=0;
    		}
    		if(lazy[x]&1){
    			Invert(ch[x][0]);
    			if(!cg[ch[x][0]]) lazy[ch[x][0]]^=1; else cg[ch[x][0]]*=-1;
    			Invert(ch[x][1]);
    			if(!cg[ch[x][1]]) lazy[ch[x][1]]^=1; else cg[ch[x][1]]*=-1;
    			lazy[x]^=1;
    		}
    		if(lazy[x]&2){
    			Swap(ch[x][0]);
    			if(!cg[ch[x][0]]) lazy[ch[x][0]]^=2;
    			Swap(ch[x][1]);
    			if(!cg[ch[x][1]]) lazy[ch[x][1]]^=2;
    			lazy[x]^=2;
    		}
    	}
    	void Rotate(int x,int &k){
    		static int y,z,l,r;
    		y=fa[x]; z=fa[y];
    		l=ch[y][0]!=x; r=l^1;
    		if(!z) k=x;
    		else ch[z][ch[z][0]!=y]=x;
    		fa[ch[x][r]]=y; fa[y]=x; fa[x]=z;
    		ch[y][l]=ch[x][r]; ch[x][r]=y;
    		Pushup(y);
    	}
    	void Splay(int x,int &k){
    		static int y,z;
    		while(x!=k){
    			y=fa[x]; z=fa[y];
    			if(y!=k) (ch[z][0]!=y)^(ch[y][0]!=x)?
    				Rotate(x,k):Rotate(y,k);
    			Rotate(x,k);
    		}
    		Pushup(x);
    	}
    	int find(int x,int num){
    		Pushdown(x);
    		if(num<=siz[ch[x][0]]) return find(ch[x][0],num);
    		else if(num==siz[ch[x][0]]+1) return x;
    		else return find(ch[x][1],num-siz[ch[x][0]]-1);
    	}
    	int Split(int l,int r){
    		static int dl,dr;
    		dl=find(rt,l); dr=find(rt,r+2);
    		Splay(dl,rt); Splay(dr,ch[dl][1]);
    		return ch[dr][0];
    	}
    	void Modify(int l,int r,int type){
    		static int p;
    		p=Split(l,r);
    		if(type==3){
    			Replace(p,(s[0]=='('?1:-1));
    			cg[p]=(s[0]=='('?1:-1); lazy[p]=0;
    		}
    		else{
    			if(type==1) Invert(p);
    			else Swap(p);
    			if(!cg[p]) lazy[p]^=type;
    			else if(type==1) cg[p]*=-1;
    		}
    		Pushup(fa[p]); Pushup(fa[fa[p]]);
    	}
    	void Build(int &x,int dad,int l,int r){
    		static char c;
    		if(l>r) return;
    		x=(l+r)>>1; fa[x]=dad;
    		Build(ch[x][0],x,l,x-1);
    		scanf(" %c",&c); key[x]=(c=='('?1:-1);
    		Build(ch[x][1],x,x+1,r);
    		Pushup(x);
    	}
    	void BorderBuild(){
    		rt=N+1;
    		key[N+1]=0; key[N+2]=0;
    		ch[N+1][1]=N+2; fa[N+2]=N+1;
    		Build(ch[N+2][0],N+2,1,N);
    		Pushup(N+2); Pushup(N+1);
    	}
    	int Query(int l,int r){
    		static int p,ANS,nl,nr;
    		p=Split(l,r);
    		nl=-pmn[p]; nr=smx[p];
    		ANS=(nl+1)/2+(nr+1)/2;
    		return ANS;
    	}
    }DT;
    int main(){
    	freopen("/home/noilinux/Documents/模块学习/2329.in","r",stdin);
    	freopen("/home/noilinux/Documents/模块学习/2329.out","w",stdout);
    	scanf("%d%d",&N,&M);
    	DT.BorderBuild();
    	for(int i=1,l,r;i<=M;i++){
    		scanf("%s",s); scanf("%d%d",&l,&r);
    		if(s[0]=='Q') printf("%d
    ",DT.Query(l,r));
    		if(s[0]=='I') DT.Modify(l,r,1);
    		if(s[0]=='S') DT.Modify(l,r,2);
    		if(s[0]=='R') scanf("%s",s),DT.Modify(l,r,3);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    kindeditor的使用
    阅读笔记(三)
    阅读笔记(二)
    架构漫谈
    阅读笔记(一)
    hdfs
    暑假周总结八
    暑假周总结七
    暑假周总结六
    暑假周总结五
  • 原文地址:https://www.cnblogs.com/zj75211/p/8108711.html
Copyright © 2020-2023  润新知