http://www.lydsy.com/JudgeOnline/problem.php?id=3224
php
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 17311 Solved: 7553数据结构
您须要写一种数据结构(可参考题目标题),来维护一些数,其中须要提供如下操做:
1. 插入x数
2. 删除x数(如有多个相同的数,因只删除一个)
3. 查询x数的排名(如有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)ui
第一行为n,表示操做的个数,下面n行每行有两个数opt和x,opt表示操做的序号(1<=opt<=6)spa
对于操做3,4,5,6每行输出一个数,表示对应答案code
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598ip
106465
84185
492737get
1.n的数据范围:n<=100000input
2.每一个数的数据范围:[-2e9,2e9]
string
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <ctime> #include <cstdlib> #define pii pair<int, int> #define mp make_pair using namespace std; template <typename ty> void read(ty &x) { x = 0; int f = 1; char ch = getchar(); while (ch > '9' || ch < '0') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x*10 + ch - '0'; ch = getchar(); } x *= f; } template <typename ty> ty Max(ty a, ty b) { return a > b ? a : b; } template <typename ty> ty Min(ty a, ty b) { return a < b ? a : b; } template <typename ty> int Chkmin(ty a, ty b) { return a > b ? a = b, 1 : 0; } template <typename ty> int Chkmax(ty a, ty b) { return a < b ? a = b, 1 : 0; } typedef long long LL; typedef double db; const int inf = 0x7fffffff; const int N = 1e5 + 16; int V[N], C[N][2], SZ[N], RD[N]; int n, sz, tot, root; void pushup(int rt) { SZ[rt] = SZ[C[rt][0]] + SZ[C[rt][1]] + 1; } int build(int val) { sz++; V[sz] = val; RD[sz] = rand(); SZ[sz] = 1; return sz; } pii split(int rt, int k) { if (!rt) return mp(0, 0); pii tmp; if (SZ[C[rt][0]] >= k) { tmp = split(C[rt][0], k); C[rt][0] = tmp.second; pushup(rt); tmp.second = rt; } else { tmp = split(C[rt][1], k - SZ[C[rt][0]] - 1); C[rt][1] = tmp.first; pushup(rt); tmp.first = rt; } return tmp; } int merge(int ra, int rb) { if (!ra) return rb; if (!rb) return ra; if (RD[ra] < RD[rb]) { C[ra][1] = merge(C[ra][1], rb); pushup(ra); return ra; } else { C[rb][0] = merge(ra, C[rb][0]); pushup(rb); return rb; } } int getkth(int rt, int val) { if (!rt) return 0; if (V[rt] >= val) return getkth(C[rt][0], val); return SZ[C[rt][0]] + 1 + getkth(C[rt][1], val); } int findkth(int rt, int k) { pii a = split(root, k - 1); pii b = split(a.second, 1); int ans = b.first; root = merge(merge(a.first, ans), b.second); return ans; } void work1(int v) { int tmp = getkth(root, v); pii a = split(root, tmp); root = merge(merge(a.first, build(v)), a.second); } void work2(int v) { int tmp = getkth(root, v); int t = findkth(root, tmp + 1); if (!t || V[t] != v) return; pii a = split(root, tmp); pii b = split(a.second, 1); root = merge(a.first, b.second); } void work3(int v) { printf("%d\n", getkth(root, v) + 1); } void work4(int v) { printf("%d\n", V[findkth(root, v)]); } void work5(int v) { printf("%d\n", V[findkth(root, getkth(root, v))]); } void work6(int v) { printf("%d\n", V[findkth(root, getkth(root, v + 1) + 1)]); } int main () { read(n); while (n --) { int opt, v; read(opt); read(v); switch(opt) { case 1: { work1(v); break; } case 2: { work2(v); break; } case 3: { work3(v); break; } case 4: { work4(v); break; } case 5: { work5(v); break; } case 6: { work6(v); break; } } } return 0; }