Splay 区间信息的维护与查询 静态模板
来源:互联网 发布:网络语言我都快长草了 编辑:程序博客网 时间:2024/05/17 04:08
Splay树除了被用作平衡二叉树之外,还有许多更高级但我们不常用的功能,比如:用Splay的旋转操作来维护区间信息,这里的旋转优先级我们可以用一个Rank来表示,则Rank[i]就代表了第i个点的优先级(对应的就是原来的序列中的位置标号),通过依据对位置标号的旋转操作,我们可以更加方便直观的维护一个区间的总和、最值等信息,并且理论复杂度与线段树相当。
#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int maxn = 2000 + 10;const int INF = 0x3f3f3f3f;struct SplayTree { int n, root; int c[maxn][2], fa[maxn], tid[maxn]; int Val[maxn], Max[maxn], Rank[maxn], size[maxn]; void init() { n = root = 0; memset(c, 0, sizeof(c)); memset(fa, 0, sizeof(fa)); memset(tid, 0, sizeof(tid)); memset(Rank, 0, sizeof(Rank)); } int Newnode(int val, int k) { ++n; Val[n] = Max[n] = val; Rank[n] = k; size[n] = 1; tid[k] = n; return n; } void Push_up(int u) { Max[u] = Val[u]; if(c[u][0]) Max[u] = max(Max[u], Max[c[u][0]]); if(c[u][1]) Max[u] = max(Max[u], Max[c[u][1]]); size[u] = size[c[u][0]] + size[c[u][1]] + 1; } void rotate(int u) { int v = fa[u], w = fa[v], t = c[v][1] == u; fa[c[u][t^1]] = v, c[v][t] = c[u][t^1]; c[u][t^1] = v; fa[u] = w; fa[v] = u; if(root == v) root = u; else c[w][c[w][1] == v] = u; Push_up(v); } void Splay(int u, int pos) { while(fa[u] != pos) { int v = fa[u], w = fa[v]; if(fa[v] == pos) rotate(u); else if((c[v][0] == u) == (c[w][0] == v)) rotate(v), rotate(u); else rotate(u), rotate(u); Push_up(u); } } void join(int u, int k, int val) { int d = k >= Rank[u]; c[u][d] = Newnode(val, k); fa[n] = u; int t = n; while(t) { Push_up(t); t = fa[t]; } Splay(n, 0); } void insert(int k, int val, int u) { int d = k >= Rank[u]; if(c[u][d]) insert(k, val, c[u][d]); else join(u, k, val); } void update(int k, int val, int u) { if(Rank[u] == k) { Val[u] = val; Push_up(u); return; } int d = k >= Rank[u]; if(c[u][d]) update(k, val, c[u][d]); Push_up(u); } int query(int x, int y) { Splay(tid[x-1], 0); Splay(tid[y+1], root); return Max[c[tid[y+1]][0]]; }}SPT[maxn], test;char s[20];int n, m;int x, y, z, x1, y1, x2, y2;int main() {#ifndef ONLINE_JUDGE freopen("yolk.in", "r", stdin); freopen("yolk.out", "w", stdout);#endif /*test.init(); test.root = test.Newnode(-INF, 0); test.insert(1, 999, test.root); test.insert(2, 0, test.root); test.insert(3, -5, test.root); test.insert(4, -INF, test.root); cout << test.query(1, 3) << endl;*/ scanf("%d%d", &n, &m); for(int i=1; i<=n; i++) { SPT[i].init(); SPT[i].root = SPT[i].Newnode(-INF, 0); for(int j=1; j<=n; j++) SPT[i].insert(j, 0, SPT[i].root); SPT[i].insert(n+1, -INF, SPT[i].root); } while(m--) { scanf("%s", s); if(s[0] == 'C') { scanf("%d%d%d", &x, &y, &z); SPT[x].update(y, z, SPT[x].root); }else { int ans = 0; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); for(int i=x1; i<=x2; i++) ans = max(ans, SPT[i].query(y1, y2)); cout << ans << endl; } } return 0;}
0 0
- Splay 区间信息的维护与查询 静态模板
- Splay 区间维护模板
- 区间信息的维护与查询
- ZOJ Monthly, March 2014,3765 Lights (Splay 基本操作,并维护区间上的信息 * 模板)
- 区间信息的维护与查询_1 2016.4.24
- 区间信息的维护与查询1(树状数组)
- 区间信息维护与查询 2016.10.13
- 区间信息的查询与维护(一)树状树组
- Splay维护区间
- HDU1754 Splay 区间维护
- 区间信息的维护和查询系列算法-树状数组
- 【转载】区间信息的维护与查询(一)——二叉索引树(Fenwick树、树状数组)
- 静态 Splay Tree 模板
- POJ 3468 A simple problem with integers Splay 区间维护模板题
- Splay tree 区间翻转 模板
- POJ 3580 SuperMemo Splay 区间维护
- HDU 3487 splay区间维护问题
- POJ3468--Splay维护区间加标记
- jenkins使用
- nefu115 斐波那契的整除 斐波纳契+打表
- H5 button元素提交表单
- ofbiz下如何实现 prototype、jQuery多库共存
- 机器学习常见算法个人总结
- Splay 区间信息的维护与查询 静态模板
- 架构漫谈(一):什么是架构?
- ofbiz 常用ant命令行
- tjut2838
- 双向队列
- hdu2476 String painter (区间DP)
- 2016年8月10号
- 树的同构
- White Water Rafting