• #Splay#U137476 序列


    题目

    给定长度为(n)的序列(Ai) ,我们将按照如下操作给(Ai) 排序,

    先找到编号最小的所在位置(x1) ,将([1,x1]) 翻转,

    再找到编号第二小的所在位置(x2) ,将([1,x2]) 翻转,

    如果有相同的(Ai) ,则按照输入顺序操作。输出所有的(xi)

    Sample Input:
    6
    3 4 5 1 6 2

    Sample Output:
    4 6 4 5 6 6


    分析

    Splay裸题,但赛时不会Splay,wtcl

    这道题的关键就是记录每个数的在Splay中的编号,

    要注意相同的数按照输入顺序操作,所以不能够直接建树,要一个个插入

    那么将操作的编号按照数的大小排序,相同编号小则优先,那么得到编号就很容易寻找排名了


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int inf=0x7fffffff,N=100011; int b[N],ans[N],n;
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline void print(int ans){
    	if (ans<0) putchar('-'),ans=-ans;
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    struct Splay{
    	int siz[N],lazy[N],cnt[N],son[N][2],fat[N],w[N],root,tot;
    	inline void pup(int x){siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];}
    	inline bool Is_R(int x){return son[fat[x]][1]==x;}
    	inline void pdown(int x){
    		if (x&&lazy[x]){
    			lazy[son[x][0]]^=1,lazy[son[x][1]]^=1;
    			swap(son[x][0],son[x][1]),lazy[x]=0;
    		}
    	} 
        inline void rotate(int x){
        	rr int Fa=fat[x],FFa=fat[Fa],wh=Is_R(x);
        	son[FFa][Is_R(Fa)]=x,fat[x]=FFa,son[Fa][wh]=son[x][wh^1];
        	fat[son[x][wh^1]]=Fa,son[x][wh^1]=Fa,fat[Fa]=x,pup(Fa),pup(x);
    	}
    	inline void update(int x,int tar){
    		if (x==tar) return;
    		update(fat[x],tar),pdown(x);
    	}
    	inline void splay(int x,int tar){
    		update(x,tar);
    		for (;fat[x]!=tar;rotate(x)){
    			rr int Fa=fat[x],FFa=fat[Fa];
    			if (FFa!=tar) rotate((Is_R(x)^Is_R(Fa))?x:Fa);
    		}
    		if (!tar) root=x;
    	}
        inline signed rank(int x){
            splay(x,0);
            return siz[son[root][0]];
        }
    	inline signed kth_site(int rk){
    		rr int now=root;
    		if (siz[now]<rk) return -1;
    		while (1){
    			pdown(now);
    			rr int lson=son[now][0];
    			if (siz[lson]+cnt[now]<rk)
    				rk-=siz[lson]+cnt[now],now=son[now][1];
    				else if (rk<=siz[lson]) now=son[now][0];
    				    else break;
    		}
    		splay(now,0);
    		return now;
    	}
    	inline void Invert(int L,int R){
    		rr int l=kth_site(L-1),r=kth_site(R+1);
    		splay(l,0),splay(r,l);
    		lazy[son[son[root][1]][0]]^=1;
    	}
    }Tre;
    bool cmp(int x,int y){return (Tre.w[x]^Tre.w[y])?Tre.w[x]<Tre.w[y]:x<y;}
    signed main(){
        n=iut(),Tre.w[1]=-inf,Tre.w[n+2]=inf;
        for (rr int i=2;i<n+2;++i) Tre.w[i]=iut();
    	for (rr int i=1;i<=n+2;++i)
    	    Tre.son[i-1][1]=i,Tre.fat[i]=i-1,Tre.lazy[i]=0,
    		    b[i]=i,Tre.cnt[i]=1,Tre.pup(i);
        Tre.root=n+2,sort(b+1,b+2+n,cmp);
    	for (rr int i=2;i<n+2;++i){
    		rr int l=i,r=Tre.rank(b[i])+1;
    		Tre.Invert(l,r),ans[i-1]=r-1;
    	}
    	for (rr int i=1;i<=n;++i) print(ans[i]),putchar(i==n?10:32);
    	return 0;
    }
    
  • 相关阅读:
    使用ConfigFilter
    读取特定文件,替换第一行内容
    sqlserver,oracle,mysql等的driver驱动,url怎么写
    Excel 数字处理
    ResultMap详解
    正则表达式
    Tomasulo algorithm
    scoreboarding
    data hazard in CPU pipeline
    差分绕线间距对阻抗的影响
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13880380.html
Copyright © 2020-2023  润新知