【BZOJ - 1058续】 动态线段树
来源:互联网 发布:unity3d 动画播放次数 编辑:程序博客网 时间:2024/06/02 05:59
· 博主是⑨
· 补充 : 蒟蒻
· 语文老师死得早
Delayyy君竟然用splay把数据水过了……Rank 1无压力……判0没天理啊> <
看了下自己程序主要耗在了离散化上...所以就想能不能不离散化什么的.
于是就试着写个动态空间的线段树.
在屏屏哥的证明下, 节点的个数是接近于 2n + nlogs - nlogn ( n 为实际元素个数, s为线段树值域 )
于是空间就是个很BT的东西……本题开了124M才水过……
但时间还是不理想 ( OJ上6s+ ), 因为实际每次新开的常数很大……哪天再想想有什么好方法吧……
动态线段树只有叶子节点有元素存在, 每次有元素冲突时 ( 叶子节点有2个元素 ), 就把该叶子节点新开左右儿子 ( 可以只开一个..视情况而定 ).
这样深度是O( logs )的...嗯.
果然不是很理想啊……就当做了个实验算了.
代码 ( 有大神能够狠狠优化的求留言= = )
#include <cstdio>#include <cstdlib>#include <algorithm>char c;#define mid ((l + r) >> 1)#define gs ((c < '0' || c > '9') && c != '-')int getint() { int wis = 0, p = 0; c = getchar(); while (gs) c = getchar(); if (c == '-') p = 1, c = getchar(); while (!gs) wis = wis * 10 + c - '0', c = getchar(); return p ? -wis : wis; }const int INF = ~0U>>1;using namespace std;int hep[500010], wap[500010], pos[500010];int right[5000010], left[5000010], tot[5000010], min_p[5000010], max_p[5000010], sav[5000010];int n, m, root, sg, sgp, min_v, max_v, x, y, dima;int v[500010], p[500010];void up(int w){ int last = hep[w]; for (; (w >> 1) && wap[hep[w >> 1]] > wap[last]; w >>= 1) pos[hep[w >> 1]] = w, hep[w] = hep[w >> 1]; pos[last] = w; hep[w] = last; }void down(int w){ int j, last = hep[w]; for (; j = w << 1, j <= sgp && (wap[hep[j]] < wap[last] || j < sgp && wap[hep[j + 1]] < wap[last]); pos[hep[j]] = w, hep[w] = hep[j], w = j) if (j < sgp && wap[hep[j]] > wap[hep[j + 1]]) ++j; pos[last] = w; hep[w] = last;}void change(int w){ if (w >> 1 && wap[hep[w >> 1]] > wap[hep[w]]) up(w); else down(w); } void update(int k){ min_p[k] = min_p[left[k]] < min_p[right[k]] ? min_p[left[k]] : min_p[right[k]]; max_p[k] = max_p[right[k]] > max_p[left[k]] ? max_p[right[k]] : max_p[left[k]]; tot[k] = min(min(tot[right[k]], tot[left[k]]), min_p[right[k]] - max_p[left[k]]);}void addnode(int p, int l, int r, int k){ if (right[k] || left[k]) { if (p <= mid) if (!left[k]) left[k] = ++sg, addnode(p, l, mid, left[k]); else addnode(p, l, mid, left[k]); else if (!right[k]) right[k] = ++sg, addnode(p, mid + 1, r, right[k]); else addnode(p, mid + 1, r, right[k]); update(k); return; } if (sav[k]) { if (sav[k] == p) { tot[k] = 0; return; } if (p <= mid && sav[k] > mid) left[k] = ++sg, addnode(p, l, mid, left[k]), right[k] = ++sg, addnode(sav[k], mid + 1, r, right[k]); else if (p > mid && sav[k] <= mid) left[k] = ++sg, addnode(sav[k], l, mid, left[k]), right[k] = ++sg, addnode(p, mid + 1, r, right[k]); else if (p > mid) right[k] = ++sg, sav[right[k]] = sav[k], addnode(p, mid + 1, r, right[k]); else if (p <= mid) left[k] = ++sg, sav[left[k]] = sav[k], addnode(p, l, mid, left[k]); sav[k] = 0; update(k); } else sav[k] = p, max_p[k] = min_p[k] = p, tot[k] = INF; }int main(){ freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); n = getint(); m = getint(); min_v = -10000; max_v = 500000000; max_p[0] = -INF / 2; min_p[0] = INF / 2; tot[0] = tot[1] = dima = INF; for (int i = 1; i <= n; ++i) v[i] = p[i] = getint(); root = ++sg; for (int i = 1; i < n; ++i) { if (tot[1] != 0) addnode(v[i], min_v, max_v, root); hep[++sgp] = i, wap[sgp] = abs(v[i + 1] - v[i]), pos[i] = i; change(i); } if (tot[1] != 0) addnode(v[n], min_v, max_v, root); for (int i = 1; i <= m; ++i) { while (c != 'I' && c != 'M') c = getchar(); if (c == 'I') { x = getint(), y = getint(); dima = min(dima, abs(p[x] - y)); p[x] = y; if (dima == 0) continue; if (x == n) continue; wap[x] = abs(v[x + 1] - p[x]); change(pos[x]); if (tot[1] == 0) continue; addnode(y, min_v, max_v, 1); } else if (scanf("%c%c%c%c", &c, &c, &c, &c), c == 'S') printf("%d\n", tot[1]); else printf("%d\n", min(dima, wap[hep[1]])); } }
- 【BZOJ - 1058续】 动态线段树
- BZOJ 3589: 动态树 树链剖分线段树
- bzoj 3589: 动态树 树链剖分+线段树
- bzoj 4574: [Zjoi2016]线段树 动态规划
- bzoj 3531(动态加点线段树,树链剖分)
- bzoj 4574: [Zjoi2016]线段树 动态规划
- bzoj 3589: 动态树 (树链剖分+线段树)
- BZOJ 3730: 震波 动态树分治 线段树 lca
- 树链剖分+动态线段树(BZOJ-3531旅行)
- BZOJ 3531 (树链剖分,线段树动态开点)
- BZOJ 4636 (动态开节点)线段树
- bzoj 2090: [Poi2010]Monotonicity 2 动态规划+线段树
- 【BZOJ】3295 [Cqoi2011]动态逆序对 树状数组+线段树
- bzoj 线段树专刊
- bzoj 1798 线段树
- BZOJ 1012 线段树
- bzoj 4388 线段树
- BZOJ 1798 线段树
- 名企招聘经典面试编程题集锦[第31-40题]
- Duilib入门文档
- 迄今见过的最好的职业规划文章
- 【基础知识】Android学习笔记--项目框架介绍
- SAP ABAP 的常用debug方式
- 【BZOJ - 1058续】 动态线段树
- 十大流行PHP开发框架介绍
- C/C++预处理过程与语句总结
- contentInset和contentOffset区别
- Log调试对应的各种含义
- Win7访问共享文件夹 记不住凭据
- SAP锁
- mac os下使用vim+ctags+taglist
- 会发声的按钮