3224: Tyvj 1728 普通平衡樹(新板子)
阿新 • • 發佈:2017-12-02
pri ati urn 多個 stdin 目標 一個 題目 page
Submit: 17048 Solved: 7429
[Submit][Status][Discuss]
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
84185
492737
2.每個數的數據範圍:[-2e9,2e9]
3224: Tyvj 1728 普通平衡樹
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17048 Solved: 7429
[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
101 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
10646584185
492737
HINT
1.n的數據範圍:n<=100000
code
更新了下板子
1 #include<cstdio> 2 3 const int N = 100010; 4 int fa[N],ch[N][2],siz[N],cnt[N],data[N]; 5 int tn,Root; 6 7 inline char nc() { 8 static char buf[100000],*p1 = buf,*p2 = buf; 9 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++; 10 } 11 inline int read() { 12 int x = 0,f = 1;char ch=nc(); 13 for (; ch<‘0‘||ch>‘9‘; ch = nc()) 14 if (ch == ‘-‘) f = -1; 15 for (; ch>=‘0‘&&ch<=‘9‘; ch = nc()) 16 x = x*10+ch-‘0‘; 17 return x * f; 18 } 19 inline int son(int x) { 20 return x == ch[fa[x]][1]; // - 21 } 22 inline void pushup(int x) { 23 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x]; 24 } 25 inline void rotate(int x) { 26 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 27 if (z) ch[z][c] = x;else Root = x;fa[x] = z; // 調整x的位置 28 ch[x][!b] = y;fa[y] = x; // 調整y的位置 29 ch[y][b] = a;if (a) fa[a] = y; // 給y另一個子節點 30 pushup(y);pushup(x); 31 } 32 inline void splay(int x,int rt) { 33 while (fa[x] != rt) { 34 int y = fa[x],z = fa[y]; 35 if (z==rt) rotate(x); 36 else { 37 if (son(x)==son(y)) rotate(y),rotate(x); 38 else rotate(x),rotate(x); 39 } 40 } 41 } 42 inline int getpre(int x) { //得到第一個比x小的數 43 int p = Root,ans; 44 while (p) { 45 if (x <= data[p]) p = ch[p][0]; 46 else ans = p,p = ch[p][1]; 47 } 48 return ans; 49 } 50 inline int getsuc(int x) { // 得到第一個比x大的數 51 int p = Root,ans; 52 while (p) { 53 if (x >= data[p]) p = ch[p][1]; 54 else ans = p,p = ch[p][0]; 55 } 56 return ans; 57 } 58 inline int getk(int k) { // 得到k的排名 59 int p = Root,ans = 0; 60 while (true) { 61 if (k < data[p]) p = ch[p][0]; 62 else { 63 ans += (ch[p][0] ? siz[ch[p][0]] : 0); 64 if (k==data[p]) { 65 splay(p,0);return ans+1; 66 } 67 ans += cnt[p]; 68 p = ch[p][1]; 69 } 70 } 71 } 72 inline int getkth(int k) { // 得到第k個數 73 int p = Root; 74 while (true) { 75 if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0]; 76 else { 77 int tmp = (ch[p][0] ? siz[ch[p][0]] : 0) + cnt[p]; 78 if (k <= tmp) return data[p]; 79 k -= tmp; p = ch[p][1]; 80 } 81 } 82 } 83 inline void Insert(int x) { // 插入 84 if (Root==0) { 85 ++tn; Root = tn; 86 ch[tn][1] = ch[tn][0] = fa[tn] = 0; 87 siz[tn] = cnt[tn] = 1;data[tn] = x; 88 return; 89 } 90 int p = Root,pa = 0; 91 while (true) { 92 if (x==data[p]) { 93 cnt[p]++;pushup(p);pushup(pa);splay(p,0);break; 94 } 95 pa = p; 96 p = ch[p][x > data[p]]; 97 if (p==0) { 98 tn++; 99 ch[tn][1] = ch[tn][0] = 0;siz[tn] = cnt[tn] = 1; 100 fa[tn] = pa;ch[pa][x > data[pa]] = tn;data[tn] = x; //- 101 pushup(pa),splay(tn,0);break; 102 } 103 } 104 } 105 inline void Clear(int x) { 106 ch[x][0] = ch[x][1] = fa[x] = siz[x] = cnt[x] = data[x] = 0; 107 } 108 inline void Delete(int x) { // 刪除 109 getk(x); 110 if (cnt[Root] > 1) {cnt[Root]--;pushup(Root);return;} 111 if (!ch[Root][0] && !ch[Root][1]) {Clear(Root);Root = 0;return;} 112 if (!ch[Root][0]) { 113 int tmp = Root;Root = ch[Root][1];fa[Root] = 0;Clear(tmp);return; 114 } 115 else if (!ch[Root][1]) { 116 int tmp = Root;Root = ch[Root][0];fa[Root] = 0;Clear(tmp);return; 117 } 118 int tmp = Root,pre = ch[Root][0];//可以是getpre(data[Root]);等價於下面的while 119 while (ch[pre][1]) pre = ch[pre][1]; 120 splay(pre,0); 121 ch[Root][1] = ch[tmp][1]; 122 fa[ch[tmp][1]] = Root; 123 Clear(tmp); 124 pushup(Root); 125 } 126 int main() { 127 int n = read(); 128 while (n--){ 129 int opt = read(),x = read(); 130 if (opt==1) Insert(x); 131 else if (opt==2) Delete(x); 132 else if (opt==3) printf("%d\n",getk(x)); 133 else if (opt==4) printf("%d\n",getkth(x)); 134 else if (opt==5) printf("%d\n",data[getpre(x)]); 135 else printf("%d\n",data[getsuc(x)]); 136 } 137 return 0; 138 }
3224: Tyvj 1728 普通平衡樹(新板子)