Submit: 19122 Solved: 8359
[Submit][Status][Discuss]
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
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
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
分析
学了一个神奇的平衡树,叫:finger tree
贴一下模板。。
code
1 #include<cstdio> 2 #include<algorithm> 3 #define ls ch[cur][0] 4 #define rs ch[cur][1] 5 6 using namespace std; 7 8 const int N = 200100; 9 10 int siz[N],val[N],ch[N][2],q[N]; 11 int tot,cnt,Root; 12 13 int getid() { 14 return tot?q[tot--]:++cnt; 15 } 16 void pushup(int cur) { 17 if (!siz[ls]) return; // - 18 siz[cur] = siz[ls] + siz[rs]; 19 val[cur] = val[rs]; 20 } 21 int newNode(int v) { 22 int cur = getid(); 23 siz[cur] = 1;val[cur] = v; 24 ls = rs = 0; 25 return cur; 26 } 27 void copyNode(int x,int y) { 28 ch[x][0] = ch[y][0];ch[x][1] = ch[y][1]; 29 siz[x] = siz[y];val[x] = val[y]; 30 } 31 int Merge(int x,int y) { 32 int cur = getid(); 33 val[cur] = val[y];siz[cur] = siz[x]+siz[y]; //--- 34 ls = x;rs = y; 35 return cur; 36 } 37 void lturn(int cur) { 38 ls = Merge(ls,ch[rs][0]); 39 q[++tot] = rs; 40 rs = ch[rs][1]; 41 } 42 void rturn(int cur) { 43 rs = Merge(ch[ls][1],rs); 44 q[++tot] = ls; 45 ls = ch[ls][0]; 46 } 47 void Maintain(int cur) { 48 if (rs && siz[ls] > siz[rs] * 4) rturn(cur); 49 if (ls && siz[rs] > siz[ls] * 4) lturn(cur); 50 } 51 void Insert(int cur,int x) { 52 if (siz[cur]==1) { 53 ls = newNode(min(val[cur],x)); 54 rs = newNode(max(val[cur],x)); 55 pushup(cur); 56 return ; 57 } 58 if (x > val[ls]) Insert(rs,x); 59 else Insert(ls,x); 60 pushup(cur); 61 Maintain(cur); 62 } 63 void Delete(int cur,int fa,int x) { 64 if (siz[cur]==1) { 65 if (ch[fa][0] == cur) copyNode(fa,ch[fa][1]); //----- 66 else copyNode(fa,ch[fa][0]); 67 return; 68 } 69 fa = cur; 70 if (x > val[ls]) Delete(rs,cur,x); 71 else Delete(ls,cur,x); 72 pushup(cur); 73 Maintain(cur); 74 } 75 int getrnk(int cur,int x) { 76 if (siz[cur]==1) return 1; 77 //{ 78 // if (x > val[cur]) return 2; 79 // return 1; 80 //} 81 if (x > val[ls]) 82 return getrnk(rs,x) + siz[ls]; 83 else return getrnk(ls,x); 84 } 85 int getkth(int cur,int k) { 86 if (siz[cur]==k) return val[cur]; 87 if (k > siz[ls]) 88 return getkth(rs,k-siz[ls]); 89 else return getkth(ls,k); 90 } 91 int main () { 92 int T; 93 scanf("%d",&T); 94 Root = newNode(1e9); 95 while (T--) { 96 int opt,x; 97 scanf("%d%d",&opt,&x); 98 if (opt==1) Insert(Root,x); 99 else if (opt==2) Delete(Root,Root,x); 100 else if (opt==3) printf("%d\n",getrnk(Root,x)); 101 else if (opt==4) printf("%d\n",getkth(Root,x)); 102 else if (opt==5) printf("%d\n",getkth(Root,getrnk(Root,x)-1)); 103 else printf("%d\n",getkth(Root,getrnk(Root,x+1))); // --- 104 } 105 return 0; 106 }
模板的变迁史:
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 6 const int N = 200100; 7 8 int siz[N],val[N],ch[N][2]; 9 int q[N],tot; 10 int cnt; 11 int Root; 12 13 int getid() { 14 return tot?q[tot--]:++cnt; 15 } 16 void pushup(int x) { 17 if (!siz[ch[x][0]]) return; // - 18 siz[x] = siz[ch[x][0]] + siz[ch[x][1]]; 19 val[x] = val[ch[x][1]]; 20 } 21 int newNode(int v) { 22 int cur = getid(); 23 siz[cur] = 1;val[cur] = v; 24 ch[cur][0] = ch[cur][1] = 0; 25 return cur; 26 } 27 void copyNode(int x,int y) { 28 ch[x][0] = ch[y][0];ch[x][1] = ch[y][1]; 29 siz[x] = siz[y];val[x] = val[y]; 30 } 31 int merge(int x,int y) { 32 int cur = getid(); 33 val[cur] = val[y];siz[cur] = siz[x]+siz[y]; //--- 34 ch[cur][0] = x;ch[cur][1] = y; 35 return cur; 36 } 37 void lturn(int cur) { 38 ch[cur][0] = merge(ch[cur][0],ch[ch[cur][1]][0]); 39 q[++tot] = ch[cur][1]; 40 ch[cur][1] = ch[ch[cur][1]][1]; 41 } 42 void rturn(int cur) { 43 ch[cur][1] = merge(ch[ch[cur][0]][1],ch[cur][1]); 44 q[++tot] = ch[cur][0]; 45 ch[cur][0] = ch[ch[cur][0]][0]; 46 } 47 void maintain(int cur) { 48 if (ch[cur][1] && siz[ch[cur][0]] > siz[ch[cur][1]] * 4) rturn(cur); 49 if (ch[cur][0] && siz[ch[cur][1]] > siz[ch[cur][0]] * 4) lturn(cur); 50 } 51 void Insert(int cur,int x) { 52 if (siz[cur]==1) { 53 ch[cur][0] = newNode(min(val[cur],x)); 54 ch[cur][1] = newNode(max(val[cur],x)); 55 pushup(cur); 56 return ; 57 } 58 if (x > val[ch[cur][0]]) Insert(ch[cur][1],x); 59 else Insert(ch[cur][0],x); 60 pushup(cur); 61 maintain(cur); 62 } 63 void Delete(int cur,int fa,int x) { 64 if (siz[cur]==1) { 65 if (ch[fa][0] == cur) copyNode(fa,ch[fa][1]); //----- 66 else copyNode(fa,ch[fa][0]); 67 return; 68 } 69 fa = cur; 70 if (x > val[ch[cur][0]]) Delete(ch[cur][1],cur,x); 71 else Delete(ch[cur][0],cur,x); 72 pushup(cur); 73 maintain(cur); 74 } 75 int rnk(int cur,int x) { 76 if (siz[cur]==1) return 1; 77 //{ 78 // if (x > val[cur]) return 2; 79 // return 1; 80 //} 81 if (x > val[ch[cur][0]]) 82 return rnk(ch[cur][1],x) + siz[ch[cur][0]]; 83 else return rnk(ch[cur][0],x); 84 } 85 int kth(int cur,int k) { 86 if (siz[cur]==k) return val[cur]; 87 if (k > siz[ch[cur][0]]) 88 return kth(ch[cur][1],k-siz[ch[cur][0]]); 89 else return kth(ch[cur][0],k); 90 } 91 int main () { 92 int T; 93 scanf("%d",&T); 94 Root = newNode(1e9); 95 while (T--) { 96 int opt,x; 97 scanf("%d%d",&opt,&x); 98 if (opt==1) Insert(Root,x); 99 else if (opt==2) Delete(Root,Root,x); 100 else if (opt==3) printf("%d\n",rnk(Root,x)); 101 else if (opt==4) printf("%d\n",kth(Root,x)); 102 else if (opt==5) printf("%d\n",kth(Root,rnk(Root,x)-1)); 103 else printf("%d\n",kth(Root,rnk(Root,x+1))); // --- 104 } 105 return 0; 106 }