3224: Tyvj 1728 普通平衡树(新板子)

3224: Tyvj 1728 普通平衡树

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

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]

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 }
时间: 2024-11-15 16:23:06

3224: Tyvj 1728 普通平衡树(新板子)的相关文章

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

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;

BZOJ 题目3224: Tyvj 1728 普通平衡树(SBT)

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

[bzoj] 3224 Tyvj 1728 普通平衡树 || 平衡树板子题

#!/bin/bash g++ make.cpp -o make -Wall g++ 1.cpp -o ac -Wall g++ sb.cpp -o sb -Wall while true; do ./make > 1.in ./ac < 1.in > 1.out ./sb < 1.in > sb.out if diff 1.out sb.out; then printf "AC!" else exit fi done 原文地址:https://www.c

bzoj 3224: Tyvj 1728 普通平衡树 &amp;&amp; loj 104 普通平衡树 (splay树)

题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 思路: splay树模板题: 推荐博客:https://blog.csdn.net/clove_unique/article/details/50630280 b站上splay树的讲解视频也可以看下,讲的很好,推荐看完视频了解了splay的原理再写 实现代码: #include<bits/stdc++.h> using namespace std; #define ll lo

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>