[BZOJ3196] [Tyvj1730] 二逼平衡树(线段树 套 Splay)
2017-05-18 14:56
393 查看
至少BZOJ过了,其他的直接弃。
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)
最外层套一颗线段树,用来表示区间,线段树下面套个splay用来维护当前线段树节点的区间。
对于第二问可以二分,看看哪个数的排名为 k。
——代码
#include <iostream> #include <cstring> #include <cstdio> #define root 1, 1, n #define lson now << 1, l, mid #define rson now << 1 | 1, mid + 1, r #define ls son[now][0] #define rs son[now][1] #define debug puts("**************"); const int MAXN = 3500001, INF = 2147483647; int n, m, sz; int seq[MAXN], rt[MAXN]; int f[MAXN], son[MAXN][2], cnt[MAXN], key[MAXN], size[MAXN]; inline int read() { int f = 1, x = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline int max(int x, int y) { return x > y ? x : y; } inline int min(int x, int y) { return x < y ? x : y; } inline void Splay_clear(int now) { f[now] = cnt[now] = key[now] = size[now] = ls = rs = 0; } inline void Splay_update(int now) { if(now) { size[now] = cnt[now]; if(ls) size[now] += size[ls]; if(rs) size[now] += size[rs]; } } inline int Splay_get(int x) { return son[f[x]][1] == x; } inline void Splay_rotate(int x) { int old = f[x], oldf = f[old], wh = Splay_get(x); son[old][wh] = son[x][wh ^ 1]; f[son[old][wh]] = old; son[x][wh ^ 1] = old; f[old] = x; if(oldf) son[oldf][son[oldf][1] == old] = x; f[x] = oldf; Splay_update(old); Splay_update(x); } inline void Splay_splay(int x) { for(int fa; fa = f[x]; Splay_rotate(x)) if(f[fa]) Splay_rotate(Splay_get(x) ^ Splay_get(fa) ? x : fa); } inline void Splay_insert(int x, int k) { int now = rt[x], fa = 0; if(!rt[x]) { rt[x] = ++sz; key[sz] = k; size[sz] = cnt[sz] = 1; return; } while(1) { if(k == key[now]) { cnt[now]++; Splay_update(now); Splay_splay(now); rt[x] = now; return; } fa = now; now = son[now][k > key[now]]; if(!now) { rt[x] = ++sz; f[sz] = fa; key[sz] = k; size[sz] = cnt[sz] = 1; son[fa][k > key[fa]] = sz; //Splay_update(fa); Splay_splay(sz); return; } } } inline int Splay_findrank(int x, int k) { int now = rt[x], ans = 0; while(1) { if(!now) return ans; if(key[now] == k) return ans + size[ls]; else if(key[now] < k) { ans += cnt[now] + size[ls]; now = rs; } else now = ls; } } inline int Splay_find(int x, int k) { int now = rt[x]; while(1) { if(key[now] > k) now = ls; else if(key[now] < k) now = rs; else { rt[x] = now; Splay_splay(now); return now; } } } inline int Splay_pre(int x) { int now = son[rt[x]][0]; while(rs) now = rs; return now; } inline int Splay_suc(int x) { int now = son[rt[x]][1]; while(ls) now = ls; return now; } inline void Splay_del(int x) { int now = rt[x]; if(cnt[now] > 1) { cnt[now]--; Splay_update(now); return; } if(!ls && !rs) { rt[x] = 0; Splay_clear(now); return; } if(!ls || !rs) { rt[x] = ls + rs; f[rt[x]] = 0; Splay_clear(now); return; } int pre = Splay_pre(x); Splay_splay(pre); rt[x] = pre; son[pre][1] = rs; f[rs] = pre; Splay_clear(now); Splay_update(pre); } inline int Splay_findpre(int x, int k) { int now = rt[x], ans = -INF; while(now) { if(key[now] < k) { ans = max(ans, key[now]); now = rs; } else now = ls; } return ans; } inline int Splay_findsuc(int x, int k) { int now = rt[x], ans = INF; while(now) { if(key[now] > k) { ans = min(ans, key[now]); now = ls; } else now = rs; } return ans; } inline void SegTree_insert(int x, int k, int now, int l, int r) { Splay_insert(now, k); if(l == r) return; int mid = (l + r) >> 1; if(x <= mid) SegTree_insert(x, k, lson); else SegTree_insert(x, k, rson); } inline int SegTree_askrank(int x, int y, int k, int now, int l, int r) { if(x <= l && r <= y) return Splay_findrank(now, k); if(l > y || r < x) return 0; int mid = (l + r) >> 1; return SegTree_askrank(x, y, k, lson) + SegTree_askrank(x, y, k, rson); } inline void SegTree_change(int x, int k, int now, int l, int r) { Splay_find(now, seq[x]); Splay_del(now); Splay_insert(now, k); if(l == r) return; int mid = (l + r) >> 1; if(x <= mid) SegTree_change(x, k, lson); else SegTree_change(x, k, rson); } inline int SegTree_findpre(int x, int y, int k, int now, int l, int r) { if(x <= l && r <= y) return Splay_findpre(now, k); if(l > y || r < x) return -INF; int mid = (l + r) >> 1; return max(SegTree_findpre(x, y, k, lson), SegTree_findpre(x, y, k, rson)); } inline int SegTree_findsuc(int x, int y, int k, int now, int l, int r) { if(x <= l && r <= y) return Splay_findsuc(now, k); if(l > y || r < x) return INF; int mid = (l + r) >> 1; return min(SegTree_findsuc(x, y, k, lson), SegTree_findsuc(x, y, k, rson)); } int main() { int i, opt, x, y, z, ans, h, t, mid, maxn = 0; n = read(); m = read(); for(i = 1; i <= n; i++) seq[i] = read(), maxn = max(maxn, seq[i]), SegTree_insert(i, seq[i], root); for(i = 1; i <= m; i++) { opt = read(); switch(opt) { case 1: { x = read(); y = read(); z = read(); printf("%d\n", SegTree_askrank(x, y, z, root) + 1); break; } case 2: { x = read(); y = read(); z = read(); h = 0, t = maxn; while(h <= t) { mid = (h + t) >> 1; if(SegTree_askrank(x, y, mid, root) + 1 <= z) h = mid + 1; else ans = mid, t = mid - 1; } printf("%d\n", ans - 1); break; } case 3: { x = read(); z = read(); SegTree_change(x, z, root); seq[x] = z; maxn = max(maxn, z); break; } case 4: { x = read(); y = read(); z = read(); printf("%d\n", SegTree_findpre(x, y, z, root)); break; } case 5: { x = read(); y = read(); z = read(); printf("%d\n", SegTree_findsuc(x, y, z, root)); break; } } } return 0; }View Code
相关文章推荐
- bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】
- bzoj3196 Tyvj 1730 二逼平衡树(树套树,线段树套splay/bit套动态开点线段树)
- BZOJ 3196 Tyvj 1730 二逼平衡树 线段树套splay
- bzoj 3196: Tyvj 1730 二逼平衡树 线段树套splay
- bzoj3196 [TYVJ1730]二逼平衡树 树套树 线段树套替罪羊树
- bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)
- BZOJ 3196(Tyvj 1730 二逼平衡树-线段树套Treap)
- bzoj3196 Tyvj 1730 二逼平衡树 线段树套treap
- [bzoj3196][Tyvj 1730][二逼平衡树] (线段树套treap)
- 【BZOJ3196】Tyvj 1730 二逼平衡树 线段树套Treap
- BZOJ3196: Tyvj 1730 二逼平衡树 (线段树 + Treap 练习题)
- BZOJ 3196 Tyvj 1730 二逼平衡树(线段树套treap)
- 【bzoj3196】Tyvj 1730 二逼平衡树 线段树套Treap
- 【bzoj3196】【坑】Tyvj 1730 二逼平衡树 线段树套Treap/Splay
- BZOJ 3196: Tyvj 1730 二逼平衡树|线段树套平衡树
- 【BZOJ 3196】二逼平衡树 线段树套splay 模板题
- BZOJ 3196 TYVJ 1730 二逼平衡树
- bzoj3196 tyvj1730 二逼平衡树
- 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树
- bzoj 3196 Tyvj 1730 二逼平衡树(主席树)