【BZOJ3224】Tyvj 1728 普通平衡树 Splay

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

Source

平衡树

Splay模板题,膜了YveH爷的模板,不过代码好长,常数还很大。。。好歹是打粗来了

  1 #include <cstdio>
  2 using namespace std;
  3 struct SplayNode
  4 {
  5     SplayNode *fa,*ch[2];
  6     SplayNode();
  7     int data,num,size;
  8     int chr() {return this==fa->ch[1];}
  9     void updata() { size=ch[0]->size+ch[1]->size+num;}
 10 }*null;
 11 SplayNode::SplayNode() {fa=ch[0]=ch[1]=null; size=0; num=1;}
 12 int n;
 13 namespace Splay
 14 {
 15     SplayNode *Root;
 16     void MakeTree()
 17     {
 18         null=new SplayNode;
 19         *null=SplayNode();
 20         Root=null;
 21     }
 22     void rotate(SplayNode *x)
 23     {
 24         SplayNode *r=x->fa;
 25         if (r==null || x==null) return;
 26         int t=x->chr();
 27         r->ch[t]=x->ch[t^1];
 28         r->ch[t]->fa=r;
 29         if (r->fa==null) Root=x;
 30         else r->fa->ch[r->chr()]=x;
 31         x->fa=r->fa;
 32         x->ch[t^1]=r;
 33         r->fa=x;
 34         r->updata();
 35         x->updata();
 36     }
 37     void splay(SplayNode *x,SplayNode *y)
 38     {
 39         for (;x->fa!=y;rotate(x))
 40             if (x->fa->fa!=y)
 41                 if (x->chr()==x->fa->chr()) rotate(x->fa);
 42                 else rotate(x);
 43     }
 44     void insert(int v)
 45     {
 46         SplayNode *r=Root;
 47         if (Root==null)
 48         {
 49             Root=new SplayNode;
 50             Root->data=v;
 51             Root->updata();
 52             return;
 53         }
 54         if (Root->data==v)
 55         {
 56             Root->num++;
 57             Root->updata();
 58             return;
 59         }
 60         while (r->ch[r->data<v]!=null)
 61         {
 62             r=r->ch[r->data<v];
 63             if (r->data==v)
 64             {
 65                 r->num++;
 66                 splay(r,null);
 67                 return;
 68             }
 69         }
 70         r->ch[r->data<v]=new SplayNode;
 71         r->ch[r->data<v]->data=v;
 72         r->ch[r->data<v]->fa=r;
 73         splay(r->ch[r->data<v],null);
 74     }
 75     SplayNode *Kth(int k)
 76     {
 77         SplayNode *r=Root;
 78         while (r!=null)
 79         {
 80             if (k<=r->ch[0]->size) r=r->ch[0];
 81             else if (k>=r->ch[0]->size+1 && k<=r->ch[0]->size+r->num) return r;
 82             else
 83             {
 84                 k=k-r->ch[0]->size-r->num;
 85                 r=r->ch[1];
 86             }
 87         }
 88         return r;
 89     }
 90     SplayNode *find(int v)
 91     {
 92         SplayNode *r=Root;
 93         while (r!=null)
 94         {
 95             if (r->data==v)
 96             {
 97                 splay(r,null);
 98                 return r;
 99             }
100             r=r->ch[r->data<v];
101         }
102         return null;
103     }
104     SplayNode *pre()
105     {
106         SplayNode *r=Root->ch[0];
107         if (r==null) return null;
108         while (r->ch[1]!=null) r=r->ch[1];
109         return r;
110     }
111     SplayNode *suc()
112     {
113         SplayNode *r=Root->ch[1];
114         if (r==null) return null;
115         while (r->ch[0]!=null) r=r->ch[0];
116         return r;
117     }
118     void del(int v)
119     {
120         find(v);
121         SplayNode *q=pre();
122         SplayNode *p=suc();
123         if (q==null && p==null)
124             if (Root->num==1) Root=null;
125             else Root->num--,Root->updata();
126         if (q==null)
127         {
128             splay(p,null);
129             if (Root->ch[0]->num==1) Root->ch[0]=null,Root->updata();
130             else Root->ch[0]->num--,splay(Root->ch[0],null);
131             return;
132         }
133         if (p==null)
134         {
135             splay(q,null);
136             if (Root->ch[1]->num==1) Root->ch[1]=null,Root->updata();
137             else Root->ch[1]->num--,splay(Root->ch[1],null);
138             return;
139         }
140         splay(q,null);
141         splay(p,q);
142         if (p->ch[0]->num==1) p->ch[0]=null,p->updata();
143         else p->ch[0]->num--,splay(p->ch[0],null);
144         return;
145     }
146 }
147 void solve()
148 {
149     int temp,x;
150     scanf("%d",&n);
151     for (int i=1;i<=n;i++)
152     {
153         scanf("%d%d",&temp,&x);
154         if (temp==1) Splay::insert(x);
155         if (temp==2) Splay::del(x);
156         if (temp==3) printf("%d\n",Splay::find(x)->ch[0]->size+1);
157         if (temp==4) printf("%d\n",Splay::Kth(x)->data);
158         if (temp==5)
159         {
160             Splay::insert(x);
161             printf("%d\n",Splay::pre()->data);
162             Splay::del(x);
163         }
164         if (temp==6)
165         {
166             Splay::insert(x);
167             printf("%d\n",Splay::suc()->data);
168             Splay::del(x);
169         }
170     }
171 }
172 int main()
173 {
174     Splay::MakeTree();
175     solve();
176     return 0;
177 }

时间: 2024-12-23 09:27:53

【BZOJ3224】Tyvj 1728 普通平衡树 Splay的相关文章

BZOJ3224: Tyvj 1728 普通平衡树[treap]

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小

bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

(其实今天好热啊? 题目大意:插入,删除,k小,前驱后继,数的排名. splay和treap裸题...过几天补个treap的 splay: #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> using namespace std; const int extar[3]={0,2147483647,-2147483647}; int fa[100010],count[

【Splay】bzoj3224 Tyvj 1728 普通平衡树

#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; #define maxn 1000000 #define INF 2147483647 int n,fa[maxn],val[maxn],c[maxn][2],root,tot,siz[maxn],cnt[maxn]; void Maintain(int x) { siz

【权值分块】bzoj3224 Tyvj 1728 普通平衡树

权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 O(1) O(1) O(sqrt(n)) O(sqrt(n)) O(sqrt(n)) O(sqrt(n)) O(sqrt(n)) 当然,因为要离散化,所以只能离线. 代码很短,很快,比我的Splay短一倍,快一倍,现在在bzoj上rank6. 1 #include<cstdio> 2 #include<algorithm> 3 #inc

bzoj3224 Tyvj 1728 普通平衡树

Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数,因输出最小的排名) 4. 查询排名为x的数 5. 求x的前驱(前驱定义为小于x,且最大的数) 6. 求x的后继(后继定义为大于x,且最小的数) Input 第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6) Output 对于操作3,4,

【权值线段树】bzoj3224 Tyvj 1728 普通平衡树

一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct Data { int v,p; }t[N]; bool cmp(const Data &a,const Data &b) { return a.v<b.v; } int T[N<<2],op[N],a[N],n,ma[N],e; void Update(int p,int v

HYSBZ 3224 Tyvj 1728 普通平衡树 splay模版

先学了splay写的 以后有空再学treap和sbt版 参考: http://blog.csdn.net/clove_unique/article/details/50630280 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector>

BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子

下面给出Splay的实现方法(复杂度证明什么的知道是 nlogn 就可以啦) 首先对于一颗可爱的二叉查找树,是不能保证最坏nlogn的复杂度(可以想象把一个升序序列插入) 所以我们需要一些非常巧妙的旋转操作 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #define N 100010 6 #define which(x) (ls[fa[(x)

bzoj 3224: Tyvj 1728 普通平衡树.

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 15114  Solved: 6570[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为