Splay树模板
来源:互联网 发布:淘宝推广佣金 编辑:程序博客网 时间:2024/06/08 11:11
#include<bits/stdc++.h>#define root_right ch[root][1]using namespace std;const int MX = 4e5 + 5;int a[MX], S[MX], n;int root, rear; //根节点,节点总数int rem[MX], tot; //经过删除后未被使用的节点int ch[MX][2], fa[MX];int val[MX], sum[MX][2];int sta[MX];int sz[MX];int gcd(int a, int b) { return b ? gcd(b, a % b) : a;}void NewNode(int &rt, int father, int v, int s) { if (tot) rt = rem[tot--]; else rt = ++rear; fa[rt] = father; ch[rt][0] = ch[rt][1] = 0; val[rt] = v; sta[rt] = s; sum[rt][s] = v; sum[rt][s ^ 1] = 0; sz[rt] = 1;}void PushUP(int rt) { int ls = ch[rt][0], rs = ch[rt][1]; sz[rt] = sz[ls] + sz[rs] + 1; sum[rt][0] = gcd(sum[ls][0], sum[rs][0]); sum[rt][1] = gcd(sum[ls][1], sum[rs][1]); if (sta[rt] == 0) sum[rt][0] = gcd(sum[rt][0], val[rt]); else sum[rt][1] = gcd(sum[rt][1], val[rt]);}void build(int &rt, int l, int r, int father) { if (l > r) return; int m = (l + r) >> 1; NewNode(rt, father, a[m], S[m]); build(ch[rt][0], l, m - 1, rt); build(ch[rt][1], m + 1, r, rt); PushUP(rt);}void init() { root = rear = tot = 0; NewNode(root, 0, 0, 0); //一共n+2个节点 NewNode(ch[root][1], root, 0, 0); for (int i = 1; i <= n; i++) scanf("%d%d", &a[i], &S[i]); build(ch[ch[root][1]][0], 1, n, ch[root][1]); PushUP(root);}void Rotate(int rt, int op) { //op=0表示左旋,op=1表示右旋 int father = fa[rt]; //PushDown(father); PushDown(rt); ch[father][!op] = ch[rt][op]; fa[ch[rt][op]] = father; if (fa[father]) ch[fa[father]][ch[fa[father]][1] == father] = rt; fa[rt] = fa[father]; ch[rt][op] = father; fa[father] = rt; PushUP(father); //father变成子节点,只要更新father}void Splay(int rt, int f) { //PushDown(rt); while (fa[rt] != f) { int father = fa[rt]; if (fa[father] == f) Rotate(rt, ch[father][0] == rt); else { int gf = fa[father]; if (ch[gf][0] == father) { if (ch[father][0] == rt) Rotate(father, 1), Rotate(rt, 1); else Rotate(rt, 0), Rotate(rt, 1); } else { if (ch[father][1] == rt) Rotate(father, 0), Rotate(rt, 0); else Rotate(rt, 1), Rotate(rt, 0); } } } PushUP(rt); //更新rt if (f == 0) root = rt;}int get_kth(int rt, int k) { int t = sz[ch[rt][0]] + 1, ret; if (t == k) ret = rt; else if (t > k) ret = get_kth(ch[rt][0], k); else ret = get_kth(ch[rt][1], k - t); return ret;}int Query(int L, int R, int s) { Splay(get_kth(root, L), 0); //将第L-1个数旋转到根节点 Splay(get_kth(root, R + 2), root); //将第R+1个数旋转到根节点的右儿子 int ans = sum[ch[ch[root][1]][0]][s]; return ans == 0 ? -1 : ans;}void Insert(int p, int v, int s) { Splay(get_kth(root, p + 1), 0); //将第p个数旋转到根节点 Splay(get_kth(root, p + 2), root); //将第p+1个数旋转到根节点的右儿子,此时该节点没有左儿子 NewNode(ch[ch[root][1]][0], ch[root][1], v, s); PushUP(ch[root][1]); PushUP(root);}void erase(int rt) { if (!rt)return; fa[rt] = 0; rem[++tot] = rt; erase(ch[rt][0]); erase(ch[rt][1]);}void Delete(int p) { Splay(get_kth(root, p), 0); //将第p-1个数旋转到根节点 Splay(get_kth(root, p + 2), root);//将第p+1个数旋转到根节点的右儿子,此时该节点左儿子为p erase(ch[ch[root][1]][0]); ch[ch[root][1]][0] = 0; PushUP(ch[root][1]); PushUP(root);}void Change1(int p) { Splay(get_kth(root, p + 1), 0); //将第p个数旋转到根节点 sta[root] ^= 1; PushUP(root);}void Change2(int p, int v) { Splay(get_kth(root, p + 1), 0); //将第p个数旋转到根节点 val[root] = v; PushUP(root);}int main() { //freopen("in.txt", "r", stdin); int m, l, r, v, s, p; char op[2]; while (~scanf("%d%d", &n, &m)) { init(); while (m--) { scanf("%s", op); if (op[0] == 'Q') { scanf("%d%d%d", &l, &r, &s); printf("%d\n", Query(l, r, s)); } if (op[0] == 'I') { scanf("%d%d%d", &p, &v, &s); Insert(p, v, s); } if (op[0] == 'D') { scanf("%d", &p); Delete(p); } if (op[0] == 'R') { scanf("%d", &p); Change1(p); } if (op[0] == 'M') { scanf("%d%d", &p, &v); Change2(p, v); } } } return 0;}
阅读全文
0 0
- Splay伸展树&模板
- 伸展树(splay)模板
- 【模板Splay】XX树
- Splay树模板
- splay树模板
- Splay伸展树模板总结
- 【模板】Splay二叉树排序
- SPLAY模板
- (模板)splay
- splay模板
- splay 模板
- splay 模板
- 【模板】splay
- splay模板
- splay模板
- Splay模板
- Splay模板
- splay 模板
- swift4.0 UITableView纯代码实现
- hanoi塔经典递归算法
- jQuery源码阅读(十三)---jQuery异步队列模块
- 【USACO1.5.3】特殊的质数肋骨
- 简单Servlet+jsp 例子的逻辑思维分析
- Splay树模板
- Jam的计数法 oj106
- 关于cmd界面无法启动mysql
- POJ
- vitrualbox Ubuntu10.04 Server安装增强功能
- HDOJ2467
- Spring笔记
- JavaWeb:报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- WPS中为Grid控件添加边框