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,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]

数据如下http://pan.baidu.com/s/1jHMJwO2

正解:平衡树。

这题就是平衡树,各种平衡树都能写。。今天晚上学了学替罪羊树,我能说我调了一晚上的原因是因为insert的传址问题吗。。

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <complex>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <cstdio>
  8 #include <vector>
  9 #include <cmath>
 10 #include <queue>
 11 #include <stack>
 12 #include <map>
 13 #include <set>
 14 #define N (100010)
 15 #define il inline
 16 #define RG register
 17 #define ll long long
 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
 19
 20 using namespace std;
 21
 22 int ch[N][2],cover[N],sz[N],val[N],del[N],st[N],Q,rt,top,tot;
 23 const double alpha=0.75;
 24
 25 il int gi(){
 26     RG int x=0,q=1; RG char ch=getchar(); while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar();
 27     if (ch==‘-‘) q=-1,ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return q*x;
 28 }
 29
 30 il void pushup(RG int x){
 31     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+(!del[x]);
 32     cover[x]=cover[ch[x][0]]+cover[ch[x][1]]+1; return;
 33 }
 34
 35 il void dfs(RG int x){
 36     if (ch[x][0]) dfs(ch[x][0]);
 37     if (!del[x]) st[++top]=x;
 38     if (ch[x][1]) dfs(ch[x][1]);
 39     sz[x]=cover[x]=ch[x][0]=ch[x][1]=0;
 40     return;
 41 }
 42
 43 il int divide(RG int l,RG int r){
 44     if (l>r) return 0; RG int mid=(l+r)>>1;
 45     ch[st[mid]][0]=divide(l,mid-1);
 46     ch[st[mid]][1]=divide(mid+1,r);
 47     pushup(st[mid]); return st[mid];
 48 }
 49
 50 il void rebuild(RG int &x){ top=0,dfs(x),x=divide(1,top); return; }
 51
 52 il int qrank(RG int x,RG int k){
 53     RG int res=1;
 54     while (x){
 55     if (k<=val[x]) x=ch[x][0];
 56     else res+=sz[ch[x][0]]+(!del[x]),x=ch[x][1];
 57     }
 58     return res;
 59 }
 60
 61 il int find(RG int x,RG int k){
 62     while (x){
 63     if (!del[x] && k==sz[ch[x][0]]+1) return val[x];
 64     if (k<=sz[ch[x][0]]) x=ch[x][0];
 65     else k-=sz[ch[x][0]]+(!del[x]),x=ch[x][1];
 66     }
 67     return val[x];
 68 }
 69
 70 il int* Insert(RG int &x,RG int k){
 71     if (!x){ val[x=++tot]=k,sz[x]=cover[x]=1; return NULL; }
 72     sz[x]++,cover[x]++; int *p=Insert(ch[x][val[x]<=k],k);
 73     if (max(cover[ch[x][0]],cover[ch[x][1]])>cover[x]*alpha) p=&x;
 74     return p;
 75 }
 76
 77 il void insert(RG int k){ int *x=Insert(rt,k); if (x) rebuild(*x); return; }
 78
 79 il void Erase(RG int x,RG int k){
 80     while (x){
 81     sz[x]--; if (!del[x] && k==sz[ch[x][0]]+1){ del[x]=1; return; }
 82     if (k<=sz[ch[x][0]]) x=ch[x][0]; else k-=sz[ch[x][0]]+(!del[x]),x=ch[x][1];
 83     }
 84     return;
 85 }
 86
 87 il void erase(RG int k){ Erase(rt,qrank(rt,k)); if (sz[rt]<cover[rt]*alpha) rebuild(rt); return; }
 88
 89 il void work(){
 90     Q=gi(); RG int type,x;
 91     while (Q--){
 92     type=gi(),x=gi();
 93     if (type==1) insert(x);
 94     if (type==2) erase(x);
 95     if (type==3) printf("%d\n",qrank(rt,x));
 96     if (type==4) printf("%d\n",find(rt,x));
 97     if (type==5) printf("%d\n",find(rt,qrank(rt,x)-1));
 98     if (type==6) printf("%d\n",find(rt,qrank(rt,x+1)));
 99     }
100     return;
101 }
102
103 int main(){
104     File("tree");
105     work();
106     return 0;
107 }
时间: 2024-09-30 09:50:55

bzoj3224 Tyvj 1728 普通平衡树的相关文章

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 普通平衡树

一个板子. #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

【权值分块】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 普通平衡树(打个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

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的前驱(前驱定义为

BZOJ 3224: Tyvj 1728 普通平衡树 treap

3224: 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)

3224: Tyvj 1728 普通平衡树

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

BZOJ 3224: Tyvj 1728 普通平衡树(BST)

treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cstdlib> #define rep(i,n) for(int i=0;i<n;