BZOJ 1500 维修数列
生活随笔
收集整理的這篇文章主要介紹了
BZOJ 1500 维修数列
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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 维修数列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java多线程学习笔记一
- 下一篇: ODPS SQL for 数据操作语言D