zoukankan      html  css  js  c++  java
  • 【题解】序列终结者

    题目链接

    (splay)维护区间加,区间翻转,区间(max).

    维护标记,区间加标记和区间翻转标记。记住两个是同级的,都要更新。

    更详细的解释请参考笔者的题解:数列。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN=5e5+10;
    const int inf=2e9;
    int n,m,id,rt,vx[MAXN];
    struct Splay_Tree{
    	int val,fa,maxn,ch[2];
    	int tag,siz,rev;
    }tr[MAXN];
    inline void pushup(int x){
    	tr[x].maxn=max(tr[tr[x].ch[0]].maxn,max(tr[tr[x].ch[1]].maxn,tr[x].val));
    	tr[x].siz=tr[tr[x].ch[0]].siz+tr[tr[x].ch[1]].siz+1;
    }
    inline int build(int l,int r,int f){
    	if(l>r)return 0;int x=++id,mid=l+r>>1;
    	tr[x].fa=f;tr[x].val=tr[x].maxn=vx[mid];
    	tr[x].ch[0]=build(l,mid-1,x),tr[x].ch[1]=build(mid+1,r,x);
    	pushup(x);return x; 
    }
    inline void rotate(int x){
    	int y=tr[x].fa,z=tr[y].fa,k=tr[y].ch[1]==x;
    	tr[z].ch[tr[z].ch[1]==y]=x;tr[x].fa=z;
    	tr[y].ch[k]=tr[x].ch[k^1];tr[tr[x].ch[k^1]].fa=y;
    	tr[x].ch[k^1]=y;tr[y].fa=x;pushup(y);pushup(x);
    }
    inline void splay(int x,int g){
    	while(tr[x].fa!=g){
    		int y=tr[x].fa,z=tr[y].fa;
    		if(z!=g)
    			(tr[y].ch[0]==x)^(tr[z].ch[0]==y)?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(!g)rt=x;
    } 
    inline void pushdown(int x){
    	int lc=tr[x].ch[0],rc=tr[x].ch[1];
    	if(tr[x].tag){
    		int p=tr[x].tag;
    		if(lc){
    			tr[lc].tag+=p;
    			tr[lc].val+=p;
    			tr[lc].maxn+=p;
    		}
    		if(rc){
    			tr[rc].tag+=p;
    			tr[rc].val+=p;
    			tr[rc].maxn+=p;
    		}
    		tr[x].tag=0;
    	}
    	if(tr[x].rev){
    		tr[x].rev=0;
    		tr[lc].rev^=1;tr[rc].rev^=1;
    		swap(tr[lc].ch[0],tr[lc].ch[1]);
    		swap(tr[rc].ch[0],tr[rc].ch[1]);
    	}
    }
    inline int Kth(int x){
    	int u=rt;
    //	if(!x)return 0;
    	while(u){
    		pushdown(u);
    		int y=tr[u].ch[0];
    		if(tr[y].siz>=x)u=y;
    		else{
    			x-=tr[y].siz+1;
    			if(!x)return u;
    			u=tr[u].ch[1];
    		}
    	}
    	return 0;
    }
    inline void change_R(int x,int y){
    	int L=Kth(x),R=Kth(y+2);
    	splay(L,0);splay(R,L);
    	int g=tr[R].ch[0];
    	tr[g].rev^=1;swap(tr[g].ch[0],tr[g].ch[1]);
    	pushup(R);pushup(L);
    }
    inline void change_A(int x,int y,int v){
    	int L=Kth(x),R=Kth(y+2);
    	splay(L,0);splay(R,L);
    	int g=tr[R].ch[0];
    	tr[g].tag+=v;tr[g].val+=v;tr[g].maxn+=v;
    	pushup(R);pushup(L);
    }
    inline int Get(int x,int y){
    	int L=Kth(x),R=Kth(y+2);
    	splay(L,0);splay(R,L);
    	return tr[tr[R].ch[0]].maxn;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	tr[0].maxn=vx[1]=vx[n+2]=-inf;rt=build(1,n+2,0);
    	while(m--){
    		int opt,L,R,X;
    		scanf("%d%d%d",&opt,&L,&R);
    		if(opt==1){
    			scanf("%d",&X);
    			change_A(L,R,X);
    		}
    		else if(opt==2)
    			change_R(L,R);
    		else if(opt==3)
    			printf("%d
    ",Get(L,R));
    	}
    	return 0;
    } 
    
  • 相关阅读:
    【Java编程思想】13.字符串
    【Java编程思想】12.通过异常处理错误
    【Java编程思想】10.内部类
    【Java编程思想】11.持有对象
    【Java编程思想】9.接口
    【Java编程思想】8.多态
    【Java编程思想】7.复用类
    【Java编程思想】6.访问权限控制
    【Java编程思想】4.控制执行流程
    Ribbon、Feign、Hystrix使用时的超时时间设置问题
  • 原文地址:https://www.cnblogs.com/h-lka/p/11517539.html
Copyright © 2011-2022 走看看