zoukankan      html  css  js  c++  java
  • bzoj4825 [Hnoi2017]单旋

    我写的第一道HNOI2017的题。。。

    记得去年(没错就是去年)不会splay,然后spaly GG现在看好water啊

    参照已经AFO的QYP巨佬的手玩结论(orzorzorz):spaly操作虽然是(O(n))的,但是只需修改几条边(So 你可以开个数组来维护splay)

    Insert:

    查出前驱和后继,x会接在深度大的下面

    以splay min为例:

    一开始x(key最小的点)并没有lson,只有father和rson;spaly之后,rson取代x的位置,x变成新的root,father没有;x的rson变成了以前的root。只需修改几个。

    splay max就把l,r互换就可以了。

    这很明显用Link-Cut Tree来维护辣。然后我顺便把BST也给维护了。(修改就几个)
    常数巨大。

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<set>
    using namespace std;
    #define il inline
    #define rg register
    #define vd void
    #define sta static
    typedef long long ll;
    il int gi(){
    	rg int x=0,f=1;rg char ch=getchar();
    	while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    const int maxn=1e5+1;
    set<int>yyb;
    namespace LCT{
    	int rt=0,ch[maxn][2],fa[maxn],siz[maxn];bool rev[maxn];
    	int f[maxn],c[maxn][2];
    	il bool isrt(const int&x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    	il vd upd(const int&x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
    	il vd down(const int&x){if(rev[x])rev[x]=0,swap(ch[x][0],ch[x][1]),rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;}
    	il vd rotate(const int&x){
    		sta int y,z,o;y=fa[x],z=fa[y],o=x==ch[y][1];
    		if(!isrt(y))ch[z][y==ch[z][1]]=x;fa[x]=z;
    		ch[y][o]=ch[x][!o];fa[ch[x][!o]]=y;
    		ch[x][!o]=y,fa[y]=x;upd(y);
    	}
    	il vd splay(const int&x){
    		sta int stk[maxn],top;stk[top=1]=x;
    		for(rg int i=x;!isrt(i);i=fa[i])stk[++top]=fa[i];
    		while(top)down(stk[top--]);
    		for(rg int y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
    			if(!isrt(y))rotate(((x==ch[y][0])^(y==ch[z][0]))?x:y);
    		upd(x);
    	}
    	il vd access(int x){for(rg int y=0;x;x=fa[y=x])splay(x),ch[x][1]=y,upd(x);}
    	il vd makeroot(const int&x){access(x),splay(x),rev[x]^=1;}
    	il vd link(const int&x,const int&y){if(x&&y)makeroot(x),fa[x]=y;}
    	il vd cut(const int&x,const int&y){if(x&&y)makeroot(x),access(y),splay(y),fa[x]=ch[y][0]=0;}
    	il int depth(const int&x){makeroot(rt);access(x),splay(x);return siz[x];}
    	il int Insert(const int&x){
    		sta set<int>::iterator it;it=yyb.insert(x).first;
    		if(rt==0){rt=x;siz[rt]=1;return 1;}
    		sta int pre,nxt;pre=nxt=0;
    		if(it!=yyb.begin())--it,pre=*it,++it;
    		++it;if(it!=yyb.end())nxt=*it;
    		if(!pre)link(x,nxt),c[nxt][0]=x,f[x]=nxt;
    		else if(!nxt)link(x,pre),c[pre][1]=x,f[x]=pre;
    		else if(depth(pre)>depth(nxt))link(x,pre),c[pre][1]=x,f[x]=pre;
    		else link(x,nxt),c[nxt][0]=x,f[x]=nxt;
    		return depth(x);
    	}
    	il int Spaly_Min(){
    		sta int x,ret;
    		x=*yyb.begin();
    		if(rt==x)return 1;
    		ret=depth(x),cut(x,f[x]),cut(x,c[x][1]),link(x,rt),link(f[x],c[x][1]);
    		c[f[x]][0]=c[x][1];f[c[x][1]]=f[x];
    		f[x]=0;c[x][1]=rt;f[rt]=x;rt=x;
    		return ret;
    	}
    	il int Spaly_Max(){
    		sta int x,ret;
    		x=*--yyb.end();
    		if(rt==x)return 1;
    		ret=depth(x),cut(x,f[x]),cut(x,c[x][0]),link(x,rt),link(f[x],c[x][0]);
    		c[f[x]][1]=c[x][0];f[c[x][0]]=f[x];
    		f[x]=0;c[x][0]=rt;f[rt]=x;rt=x;
    		return ret;
    	}
    	il vd Del_Root(){
    		yyb.erase(yyb.find(rt));
    		if(c[rt][0])cut(rt,c[rt][0]),rt=c[rt][0],f[rt]=0;
    		else if(c[rt][1])cut(rt,c[rt][1]),rt=c[rt][1],f[rt]=0;
    		else rt=0;
    	}
    }using namespace LCT;
    int main(){
    #ifdef xzz
    	freopen("4825.in","r",stdin);
    	freopen("4825.out","w",stdout);
    #endif
    	int m=gi();sta int opt[maxn],x[maxn],y[maxn];
    	for(rg int i=1;i<=m;++i){opt[i]=gi();if(opt[i]==1)x[i]=gi(),y[++y[0]]=x[i];}
    	sort(y+1,y+y[0]+1);
    	for(rg int i=1;i<=m;++i)if(opt[i]==1)x[i]=lower_bound(y+1,y+y[0]+1,x[i])-y;
    	for(rg int i=1;i<=m;++i){
    		if(opt[i]==1)printf("%d
    ",Insert(x[i]));
    		else if(opt[i]==2)printf("%d
    ",Spaly_Min());
    		else if(opt[i]==3)printf("%d
    ",Spaly_Max());
    		else if(opt[i]==4)printf("%d
    ",Spaly_Min()),Del_Root();
    		else printf("%d
    ",Spaly_Max()),Del_Root();
    	}
       	return 0;
    }
    
  • 相关阅读:
    【珍惜时间】 vant-finance-mobile
    【珍惜时间】h5-tzl
    利用popstate事件和window下的history对象处理浏览器跳转问题
    在salesforce中如何获取Security Token
    加密与安全:非对称加密算法 RSA 1024 公钥、秘钥、明文和密文长度
    Android studio:URI is not registered 的解决办法
    解决support包引起的AndroidStudio编译报错
    解决Invalid Plugin needs a valid package.json
    Android Studio Error:Execution failed for task ':app:compileDebugJavaWithJavac' 根本解决方法
    Android Studio 3.0——unable to resolve dependency for cordovalib
  • 原文地址:https://www.cnblogs.com/xzz_233/p/8168708.html
Copyright © 2011-2022 走看看