【BZOJ - 1058续】 动态线段树
2013-03-08 14:45
281 查看
· 博主是⑨
· 补充 : 蒟蒻
· 语文老师死得早
Delayyy君竟然用splay把数据水过了……Rank 1无压力……判0没天理啊> <
看了下自己程序主要耗在了离散化上...所以就想能不能不离散化什么的.
于是就试着写个动态空间的线段树.
在屏屏哥的证明下, 节点的个数是接近于 2n + nlogs - nlogn ( n 为实际元素个数, s为线段树值域 )
于是空间就是个很BT的东西……本题开了124M才水过……
但时间还是不理想 ( OJ上6s+ ), 因为实际每次新开的常数很大……哪天再想想有什么好方法吧……
动态线段树只有叶子节点有元素存在, 每次有元素冲突时 ( 叶子节点有2个元素 ), 就把该叶子节点新开左右儿子 ( 可以只开一个..视情况而定 ).
这样深度是O( logs )的...嗯.
果然不是很理想啊……就当做了个实验算了.
代码 ( 有大神能够狠狠优化的求留言= = )
· 补充 : 蒟蒻
· 语文老师死得早
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 , 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]])); } }
相关文章推荐
- 【bzoj3295】[Cqoi2011]动态逆序对 线段树套SBT
- BZOJ 2124 浅谈线段树动态维护双HASH判值域回文串
- BZOJ 3295 CQOI 2011 动态逆序对 线段树套Treap
- [BZOJ3295][Cqoi2011]动态逆序对(树状数组套线段树||cdq分治)
- 【bzoj3295】[Cqoi2011]动态逆序对 树套树 线段树套替罪羊树
- bzoj3065 带插入区间K小值(替罪羊树套动态开点线段树)
- [Bzoj5358][Lydsy1805月赛]口算训练(预处理+动态开点线段树)
- BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树
- bzoj 4999 This problem is too simple 树链剖分+动态开点线段树
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
- bzoj5155 [Tjoi2014]电源插排(动态开点线段树)
- 【BZOJ3939】Cow Hopscotch(动态开点线段树)
- BZOJ-3531 旅行 树链剖分+动态开点线段树
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
- 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
- BZOJ[3531][Sdoi2014]旅行 树链剖分+动态开点线段树
- 【bzoj3531】[Sdoi2014]旅行 动态开点的线段树
- [BZOJ4372][动态树分治(点分树)][动态开点线段树]烁烁的游戏
- bzoj 3439: Kpm的MC密码 Trie+动态开点线段树