3224: Tyvj 1728 普通平衡树(finger tree)

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
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

Sample Output

106465
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 }
View Code

 

模板的变迁史:

  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 }
View Code

 

指针

 1 // luogu-judger-enable-o2
 2 #include<cstdio>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 
 7 const int MAXN = 400010;
 8 
 9 struct Node {
10     int val,size;
11     Node *ls,*rs;
12     Node():val(0),size(0),ls(NULL),rs(NULL) { } 
13     Node(int v,int s,Node *l,Node *r) {
14         val = v,size = s,ls = l,rs = r;
15     }
16     bool isleaf() {
17         return ls == NULL;
18     }
19     void pushup() {
20         if (!isleaf()) {
21             size = ls->size + rs->size;
22             val = max(ls->val,rs->val);
23         }
24     }
25 }pool[MAXN];
26 
27 Node *newNode(int val,int size,Node *ls,Node *rs) {
28     static int cnt = 0;
29     pool[cnt] = Node(val,size,ls,rs);
30     return &pool[cnt++];
31 }
32 
33 void insert(Node *&cur,int x) {
34     if (cur==NULL) cur = newNode(x,1,NULL,NULL);
35     else {
36         if (cur->isleaf()) {
37             cur->ls = newNode(min(x,cur->val),1,NULL,NULL);
38             cur->rs = newNode(max(x,cur->val),1,NULL,NULL);
39         }
40         else {
41             if (x > cur->ls->val) insert(cur->rs,x);
42             else insert(cur->ls,x);
43         }
44         cur -> pushup();
45     }
46 }
47 void erase(Node *cur,Node *fa,int x) {
48     if (cur->isleaf()) {
49         if (fa->ls == cur) *fa = *fa->rs;
50         else *fa = *fa->ls;
51     }
52     else  {
53         if (x > cur->ls->val) erase(cur->rs,cur,x);
54         else erase(cur->ls,cur,x);
55         cur -> pushup();
56     }
57 }
58 int rnk(Node *cur,int x) {
59     if (cur->isleaf()) {
60         if (x > cur->val) return 2;
61         return 1;
62     }
63     else {
64         if (x > cur->ls->val) 
65             return rnk(cur->rs,x)+cur->ls->size;
66         else return rnk(cur->ls,x);
67     }
68 }
69 int kth(Node *cur,int k) {
70     if (cur->isleaf()) return cur->val;
71     else {
72         if (k > cur->ls->size) 
73             return kth(cur->rs,k - cur->ls->size);
74         else return kth(cur->ls,k);
75     }
76 }
77 int main () {
78     int T;
79     scanf("%d",&T);
80     Node *root = NULL;
81     while (T--) {
82         int opt,x;
83         scanf("%d%d",&opt,&x);
84         if (opt==1) insert(root,x);
85         else if (opt==2) erase(root,root,x);
86         else if (opt==3) printf("%d\n",rnk(root,x));
87         else if (opt==4) printf("%d\n",kth(root,x));
88         else if (opt==5) printf("%d\n",kth(root,rnk(root,x)-1));
89         else  printf("%d\n",kth(root,rnk(root,x+1)));
90     }
91     return 0;
92 }
View Code

 

 

posted @ 2018-02-11 14:05  MJT12044  阅读(606)  评论(1编辑  收藏  举报