Splay序列操作的大模板题

这个真的是噩梦。。调了整整一个晚上,可以说完全被榨干了orz。。
因为我的splay写的实在是太丑了,手动加的哨兵节点,开头忘记pushup了,找了一晚上才找到。。。
还有就是0节点的mx也要设置成-INF,否则会影响我门原树叶子结点的mx。。其他的就靠造化了。。

还要注意的是数组500000就够了,剩下的靠内存池维护,不然在BZOJ上会爆内存,但是他显示的是TLE。。不仅题目坑,这个评测也挺不友好的。。但是在洛谷还是可以过的

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){int X = 0, w = 0; char ch = 0;while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){A ans = 1;for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;return ans;
}const int N = 500005;
int ch[N][2], sum[N], mx[N], lx[N], rx[N], lazy[N], rev[N], val[N], fa[N], size[N], a[N];
int tot, n, m, root;
queue<int> q;
int newNode(int p, int v){if(!q.empty()){int ret = q.front(); q.pop();sum[ret] = v, mx[ret] = val[ret] = v;if(v >= 0) lx[ret] = rx[ret] = v;else lx[ret] = rx[ret] = 0;lazy[ret] = rev[ret] = ch[ret][0] = ch[ret][1] = 0;fa[ret] = p, size[ret] = 1;return ret;}else{sum[++tot] = v, mx[tot] = val[tot] = v;if(v >= 0) lx[tot] = rx[tot] = v;else lx[tot] = rx[tot] = 0;lazy[tot] = rev[tot] = ch[tot][0] = ch[tot][1] = 0;fa[tot] = p, size[tot] = 1;return tot;}
}void recycle(int x){if(!x) return;recycle(ch[x][0]);recycle(ch[x][1]);q.push(x);
}void push_up(int x){int l = ch[x][0], r = ch[x][1];sum[x] = sum[l] + sum[r] + val[x];size[x] = size[l] + size[r] + 1;lx[x] = max(lx[l], sum[l] + val[x] + lx[r]);rx[x] = max(rx[r], sum[r] + val[x] + rx[l]);mx[x] = max(mx[l], mx[r], rx[l] + val[x] + lx[r]);
}void push_down(int x){int l = ch[x][0], r = ch[x][1];if(lazy[x]){lazy[x] = rev[x] = 0;if(l) sum[l] = val[x] * size[l], val[l] = val[x], lazy[l] = 1;if(r) sum[r] = val[x] * size[r], val[r] = val[x], lazy[r] = 1;if(val[x] >= 0){if(l) lx[l] = rx[l] = mx[l] = sum[l];if(r) lx[r] = rx[r] = mx[r] = sum[r];}else{if(l) lx[l] = rx[l] = 0, mx[l] = val[x];if(r) lx[r] = rx[r] = 0, mx[r] = val[x];}}if(rev[x]){rev[x] ^= 1, rev[l] ^= 1, rev[r] ^= 1;swap(lx[l], rx[l]), swap(lx[r], rx[r]);swap(ch[l][0], ch[l][1]), swap(ch[r][0], ch[r][1]);}
}void rotate(int x){int y = fa[x], z = fa[y], p = (ch[y][1] == x) ^ 1;push_down(y), push_down(x);ch[y][p^1] = ch[x][p], fa[ch[x][p]] = y;fa[x] = z, ch[z][ch[z][1] == y] = x, fa[y] = x, ch[x][p] = y;push_up(y), push_up(x);
}void splay(int x, int goal){if(x == goal) return;while(fa[x] != goal){int y = fa[x], z = fa[y];if(z != goal){if((ch[y][0] == x) ^ (ch[z][0] == y)) rotate(x);else rotate(y);}rotate(x);}push_up(x);if(goal == 0) root = x;
}int find(int k){if(!root) return 0;int cur = root, r = size[ch[cur][0]];while(1){push_down(cur);if(r < k){k -= r + 1;cur = ch[cur][1];}else{if(r > k) cur = ch[cur][0];else return cur;}r = size[ch[cur][0]];}
}int buildTree(int p, int l, int r){if(l > r) return 0;int mid = (l + r) >> 1;int cur = newNode(p, a[mid]);ch[cur][0] = buildTree(cur, l, mid - 1);ch[cur][1] = buildTree(cur, mid + 1, r);push_up(cur);return cur;
}void insert(int pos, int k){if(!k) return;for(int i = 1; i <= k; i ++) a[i] = read();int x = find(pos), y = find(pos + 1);splay(x, 0), splay(y, root);ch[y][0] = buildTree(y, 1, k);push_up(y), push_up(x);
}void erase(int pos, int k){if(!k) return;int x = find(pos - 1), y = find(pos + k);splay(x, 0), splay(y, root);recycle(ch[y][0]);ch[y][0] = 0;push_up(y), push_up(x);
}void modify(int pos, int k, int c){if(!k) return;int x = find(pos - 1), y = find(pos + k);splay(x, 0), splay(y, root);int key = ch[y][0];val[key] = c, sum[key] = size[key] * c, lazy[key] = 1;if(val[key] >= 0) mx[key] = lx[key] = rx[key] = sum[key];else mx[key] = c, lx[key] = rx[key] = 0;push_up(y), push_up(x);
}void reverse(int pos, int k){if(!k) return;int x = find(pos - 1), y = find(pos + k);splay(x, 0), splay(y, root);int key = ch[y][0];if(!lazy[key]){rev[key] ^= 1;swap(lx[key], rx[key]), swap(ch[key][0], ch[key][1]);push_up(y), push_up(x);}
}int getSum(int pos, int k){if(!k) return 0;int x = find(pos - 1), y = find(pos + k);splay(x, 0), splay(y, root);return sum[ch[y][0]];
}int getMax(){return mx[root];
}int main(){n = read(), m = read();mx[0] = -INF;root = newNode(0, -INF), ch[root][1] = newNode(root, -INF);for(int i = 1; i <= n; i ++) a[i] = read();ch[ch[root][1]][0] = buildTree(ch[root][1], 1, n);push_up(ch[root][1]), push_up(root);while(m --){char opt[20]; scanf("%s", opt);if(opt[2] == 'X') printf("%d\n", getMax());else{int pos = read(), tot = read();if(opt[0] == 'I') insert(pos, tot);else if(opt[0] == 'D') erase(pos, tot);else if(opt[0] == 'M') { int c = read(); modify(pos, tot, c); }else if(opt[0] == 'R') reverse(pos, tot);else if(opt[0] == 'G') printf("%d\n", getSum(pos, tot));}}return 0;
}

转载于:https://www.cnblogs.com/onionQAQ/p/10699617.html

BZOJ 1500 维修数列相关推荐

  1. [BZOJ 1500] [NOI2005] 维修数列

    题目链接:BZOJ - 1500 题目分析 我要先说一下,这道题我写了一晚上,然后Debug了一整个白天..........再一次被自己的蒟蒻程度震惊= = 这道题是传说中的Splay维护数列的Bos ...

  2. BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay)

    BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay) 手动博客搬家: 本文发表于20180825 00:34:49, 原地址https://blog.csdn.ne ...

  3. [BZOJ1500][NOI2005]维修数列(splay)

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 16266  Solved: 5410 [Submit][Sta ...

  4. 【BZOJ1500】[NOI2005]维修数列 Splay

    [BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目. 第2 ...

  5. 数据结构之fhq-treap——Chef and Sets,[HNOI2012]永无乡,Play with Chain,[NOI2005]维修数列(结构体版代码)

    因为非常板,所以主要是代码 Tyvj 1728 普通平衡树 Chef and Sets [HNOI2012]永无乡 Play with Chain [NOI2005]维修数列 题目很水,所以可能会出现 ...

  6. bzoj 1500 [NOI 2005] 维修数列

    题目大意不多说了 貌似每个苦逼的acmer都要做一下这个splay树的模版题目吧 还是有很多操作的,估计够以后当模版了.... 1 #include <cstdio> 2 #include ...

  7. 1500: [NOI2005]维修数列 (Splay)

    1W1A(inf开太大) #include<algorithm> #include<iostream> #include<cstring> #include< ...

  8. BZOJ1500 [NOI2005]维修数列(Splay tree)

    [Submit][Status][Discuss] Description 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线' _ '表示实际输入文件中的空格 Inp ...

  9. bzoj 2656: [Zjoi2012]数列(sequence)(简单高精度模板2.0)

    2656: [Zjoi2012]数列(sequence) Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 1663  Solved: 860 [Subm ...

最新文章

  1. 是不是“异常”让我的脑子糊涂了?
  2. document对象详解
  3. 利用angular4和nodejs-express构建一个简单的网站(九)—用户登录
  4. Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
  5. c语言实现循环单链表
  6. Spark笔记:RDD基本操作(上)
  7. 经典面试题(19):以下代码将输出的结果是什么?
  8. 初学UML,画了几个UML图
  9. 解压deb_Linux填坑记:很全面的解压和压缩命令集合
  10. 我所理解的JVM(三):字节码的执行
  11. HDU1285确定比赛名次(拓扑排序+优先队列)
  12. IPv6-IPv4过渡技术详解及配置实例
  13. 爬虫:信息提取的一般方法
  14. 使用梯度上升法求解 PCA 问题
  15. SAP 上传图片至系统
  16. 【XSY2271】青蛙(栈)
  17. sap exceptions处理
  18. MySQL出现Access denied for user ‘xxx‘@‘%‘ to database ‘xxxx‘问题
  19. 什么是低功耗蓝牙技术
  20. 如何选购计算机硬件,如何选购电脑硬件 选购电脑硬件技巧【详细介绍】

热门文章

  1. 【物联网智能网关-03】GPRS模块中文短信收发
  2. Heritrix 1.14.4的配置和初次使用
  3. 汉语编程能获得诺贝尔奖
  4. 擴展PictureBox的一個組件
  5. django-allauth定制模板(转载)
  6. dpkg: 錯誤: 分析檔案 '/var/lib/dpkg/updates/0001' 的第 0 行附近: 欄位名稱 `#padding' 中有換行
  7. RStudio修改快捷键确保每次运行都是从头运行所有代码
  8. leetcode:图相关算法
  9. 网络杂谈, Docker, MongoDB
  10. 几种常用的优化方法梯度下降法、牛顿法、)