• BZOJ 1861 [Zjoi2006]Book 书架 ——Splay


    【题目分析】

        模板题目。

        首尾两个虚拟结点,十分方便操作。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    
    #include <map>
    #include <set>
    #include <queue>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 500005
    #define inf 0x3f3f3f3f
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define L ch[o][0]
    #define R ch[o][1] 
    
    void Finout()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        #endif
    }
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int n,m;
    
    struct Bit_Tree{
    	int a[maxn],b[maxn];
    	void add(int x,int y,int z)
    	{
    		for (int i=x;i<=n;i+=i&(-i)) b[i]+=z;
    		for (int i=y+1;i<=n;i+=i&(-i)) b[i]-=z;
    		for (int i=x;i<=n;i+=i&(-i)) a[i]+=(n-x)*z;
    		for (int i=y+1;i<=n;i+=i&(-i)) a[i]-=(n-y-1)*z;
    	}
    	int getsum(int x)
    	{
    		int ret=0,tmp=0;
    		for (int i=x;i;i-=i&(-i)) ret+=a[i];
    		for (int i=x;i;i-=i&(-i)) tmp+=b[i];
    		return ret-(n-x-1)*tmp;
    	}
    	void init()
    	{
    		memset(a,0,sizeof a);
    		memset(b,0,sizeof b);
    	}
    }t;
    
    int rt=0,a[maxn],s,T,id[maxn],cnt=0;
    char opt[10];
    int num[maxn],ch[maxn][2],siz[maxn],fa[maxn],list[maxn];
    
    void update(int o)
    {
    	siz[o]=siz[L]+siz[R]+1;
    }
    
    void rot(int x,int &k)
    {
    //	cout<<"rot"<<x<<endl;
        int y=fa[x],z=fa[y],l,r;
        if (ch[y][0]==x) l=0; else l=1;
        r=l^1;
        if (y==k) k=x;
        else
        {
            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;
        update(y); update(x); 
    }
    
    void splay(int x,int &k)
    {
        int y,z;
        while (x!=k)
        {
            y=fa[x];z=fa[y];
            if (y!=k)
            {
                if ((ch[z][0]==y)^(ch[y][0]==x)) rot(x,k);
                else rot(y,k);
            }
            rot(x,k);
        }
    }
    
    void ins(int & o,int x,int lst)
    {
    	if (!o)
    	{
    		o=++cnt;
    		fa[o]=lst;
    		num[o]=x;
    		siz[o]=1;
    		list[o]=a[x-1];
    		splay(o,rt);
    		return ;
    	}
    	if (x<num[o]) ins(ch[o][0],x,o);
    	else ins(ch[o][1],x,o);
    	update(o);
    }
    
    int find(int o,int x)
    {
    //	cout<<"qnum"<<num[o]<<" "<<x<<endl; 
    	if (siz[L]+1==x) return o;
    	if (siz[L]>=x) return find(L,x);
    	else return find(R,x-siz[L]-1);
    }
    
    void print(int o)
    {
    	if (!o) return ;
    	print(L);
    //	cout<<"now is "<<o<<endl;
    //	cout<<L<<" "<<R<<endl;
    //	cout<<num[o]<<" "<<siz[o]<<endl;
    	cout<<num[o]<<" ";
    	print(R);
    }
    
    
    void Mov(int o,int k)
    {
    	splay(o,rt);
    	int pre=find(rt,siz[L]),nxt=find(rt,siz[L]+2);
    	splay(pre,rt); splay(nxt,ch[rt][1]);
    	ch[nxt][0]=0; fa[o]=0;
    	update(nxt); update(pre);
    	splay(nxt,rt);
    	pre=find(rt,k-1);nxt=find(rt,k);
    	splay(pre,rt); splay(nxt,ch[rt][1]);
    	ch[nxt][0]=o; fa[o]=nxt;
    	splay(o,rt);
    }
    
    int main()
    {
        Finout();
        scanf("%d%d",&n,&m);
        F(i,1,n) scanf("%d",&a[i]),id[a[i]]=i+1;
        F(i,0,n+1) ins(rt,i,0);
    //    print(rt);
    //    cout<<rt<<endl;
        F(i,1,m)
        {
    //    	print(rt);
    //    	cout<<endl;
        	scanf("%s",opt);
        	scanf("%d",&s);
        	if (opt[0]=='Q')
    		{
    //			cout<<"QUERY"<<endl;
    			printf("%d
    ",a[find(rt,s+1)-1]);
    		}
        	else if (opt[0]=='A')
        	{
    //    		cout<<"ASK"<<endl;
        		splay(id[s],rt);
        		printf("%d
    ",siz[ch[rt][0]]-1);
    		}
    		else if (opt[0]=='T')
    		{
    //			cout<<"TOP"<<endl;
    			Mov(id[s],1+1);
    		}
    		else if (opt[0]=='B')
    		{
    //			cout<<"BOT"<<endl;
    			Mov(id[s],n+1);
    		}
    		else
    		{
    			T=Getint();
    			splay(id[s],rt);
    			int tmp=siz[ch[rt][0]];
    			Mov(id[s],tmp+T+1);
    		}
    	}
    }
    

      

  • 相关阅读:
    RAC环境下ORACLE序列缓存导致序列混乱
    zzu edu
    windows下的神器
    关于VO、PO的理解——JAVA的(PO,VO,TO,BO,DAO,POJO)解释
    enum学习
    maven 引入本地 jar
    eclipse F6和F8的问题
    记一个搜索网盘资源的网站
    多表查询, 聚集查询和分组查询
    winserver2008安装tomcat+mysql+httpd+redis环境
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6271231.html
Copyright © 2020-2023  润新知