• Splay模板bzoj3224


    解析:http://www.cnblogs.com/zwfymqz/p/7898210.html

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct one
    {
    	int v,fa,ch[2],rec,sum;
    };
    one tree[500000];
    int n,tot=0,pointnum=0;
    #define root tree[0].ch[1]
    int iden(int x)
    {
    	return tree[tree[x].fa].ch[0]==x?0:1;
    }
    inline void connect(int x,int fa,int how)
    {
    	tree[x].fa=fa;
    	tree[fa].ch[how]=x;
    }
    inline void update(int x)
    {
    	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;}
    inline void rotate(int x)
    {
    	int Y=tree[x].fa;
    	int R=tree[Y].fa;
    	int Yson=iden(x);
    	int Rson=iden(Y);
    	int B=tree[x].ch[Yson^1];
    	connect(x,R,Rson);
    	connect(Y,x,Yson^1);
    	connect(B,Y,Yson);
    	update(Y);update(x);
    }
    void splay(int x,int to)
    {
    	to=tree[to].fa;
    	while(tree[x].fa!=to)
    	{
    		if(tree[tree[x].fa].fa==to)rotate(x);
    		else if(iden(x)==iden(tree[x].fa))rotate(tree[x].fa),rotate(x);
    		else rotate(x),rotate(x);
    	}
    }
    void newpoint(int v,int fa)
    {
    	tree[++tot].v=v;
    	tree[tot].fa=fa;
    	tree[tot].sum=tree[tot].rec=1;
    }
    int build(int v)
    {
    	pointnum++;
    	if(tot==0){root=1;newpoint(v,0);}
    	else
    	{
    		int now=root;
    		while(1)
    		{
    			tree[now].sum++;
    			if(tree[now].v==v){tree[now].rec++;return now;}
    			int nxt=v<tree[now].v?0:1;
    			if(!tree[now].ch[nxt])
    			{
    				newpoint(v,now);tree[now].ch[nxt]=tot;return tot;
    			}
    			now=tree[now].ch[nxt];
    		}
    	}
    	return 0;
    }
    inline void dele(int x)
    {
    	tree[x].v=tree[x].fa=tree[x].ch[0]=tree[x].rec=tree[x].sum=tree[x].ch[1]=0;
    	if(x==tot)tot--;
    }
    int find(int v)
    {
    	int now=root;
    	while(1)
    	{
    		if(tree[now].v==v){splay(now,root);return now;}
    		int nxt=v<tree[now].v?0:1;
    		if(!tree[now].ch[nxt])return 0;
    		now=tree[now].ch[nxt];
    	}
    }
    void pop(int v)
    {
    	int deal=find(v);
    	if(!deal)return;
    	pointnum--;
    	if(tree[deal].rec>1){tree[deal].sum--;tree[deal].rec--;return;}
    	if(!tree[deal].ch[0])root=tree[deal].ch[1],tree[root].fa=0;
    	else
    	{
    		int le=tree[deal].ch[0];
    		while(tree[le].ch[1])le=tree[le].ch[1];
    		splay(le,tree[deal].ch[0]);
    		int ri=tree[deal].ch[1];
    		connect(ri,le,1);
    		connect(le,0,1);
    		update(le);
    	}
    	dele(deal);
    }
    void insert(int v)
    {
    	int p=build(v);splay(p,root);
    }
    int rank(int v)
    {
    	int ans=0,now=root;
    	while(1)
    	{
    		if(tree[now].v==v){ans+=tree[tree[now].ch[0]].sum+1;splay(now,root);return ans;}
    		if(now==0)return 0;
    		if(v<tree[now].v)now=tree[now].ch[0];
    		else ans+=tree[tree[now].ch[0]].sum+tree[now].rec,now=tree[now].ch[1];
    	}
    }
    int arank(int x)
    {
    	int now=root;
    	while(1)
    	{
    		int used=tree[now].sum-tree[tree[now].ch[1]].sum;
    		if(x>tree[tree[now].ch[0]].sum&&x<=used)break;
    		if(x<used)now=tree[now].ch[0];
    		else x-=used,now=tree[now].ch[1];
    	}
    	splay(now,root);
    	return tree[now].v;
    }
    int lower(int v)
    {
    	int now=root;
    	int ans=-100000000;
    	while(now)
    	{
    		if(tree[now].v<v&&tree[now].v>ans)ans=tree[now].v;
    		if(v>tree[now].v)now=tree[now].ch[1];
    		else now=tree[now].ch[0];
    	}
    	return ans;
    }
    int upper(int v)
    {
    	int now=root;
    	int ans=100000000;
    	while(now)
    	{
    		if(tree[now].v>v&&tree[now].v<ans)ans=tree[now].v;
    		if(tree[now].v>v)now=tree[now].ch[0];
    		else now=tree[now].ch[1];
    	}
    	return ans;
    }
    int main()
    {
    	//freopen("xf.in","r",stdin);
    	scanf("%d",&n);
    	int p1,p2;
    	for(int i=1;i<=n;i++)
    	{
    		p1=read();p2=read();
    		if(p1==1)insert(p2);
    		else if(p1==2)pop(p2);
    		else if(p1==3)printf("%d
    ",rank(p2));
    		else if(p1==4)printf("%d
    ",arank(p2));
    		else if(p1==5)printf("%d
    ",lower(p2));
    		else if(p1==6)printf("%d
    ",upper(p2));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    计算几何——直线交点poj1269
    计算几何——线段和直线判交点poj3304
    mysql优化
    MyBatis的返回参数类型和查询结果遍历
    Java中HashMap遍历的两种方式
    Java 常用排序算法/程序员必须掌握的 8大排序算法
    手动挡车该如何磨合
    手动挡你会开吗 八招教你开好手动挡车型
    开手动挡车10大技巧 老司机也不一定全知道!
    手动挡汽车操作必须知道的9大误区
  • 原文地址:https://www.cnblogs.com/mybing/p/8427974.html
Copyright © 2020-2023  润新知