bzoj 1500 维修数列
2016-03-26 10:28
204 查看
splay插入,删除,区间翻转,区间修改,区间求和,区间最大子段和。
要把splay 的删除后的结点编号,重新利用,不然会MLE。初始化的时候,a[0] = a[n+1] = -inf;
sum[0] = 0; lsum[0] = rsum[0] = mx[0] = -inf;不然区间求子段和的时候有负数的时候就跪了(因为lsum[0], rsum[0], mx[0]默认是0)。
要把splay 的删除后的结点编号,重新利用,不然会MLE。初始化的时候,a[0] = a[n+1] = -inf;
sum[0] = 0; lsum[0] = rsum[0] = mx[0] = -inf;不然区间求子段和的时候有负数的时候就跪了(因为lsum[0], rsum[0], mx[0]默认是0)。
#include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; #pragma comment(linxer, "/STACK:102400000,102400000") #define LL long long #define pii pair<int, int> #define MP maxe_pair #define ls i << 1 #define rs ls | 1 #define md (ll + rr >> 1) #define lson ll, md, ls #define rson md + 1, rr, rs #define mod 1000000007 #define inf 0x3f3f3f3f #define N 700020 #define M 500010 int ch [2], pre , sz , a , val ; int sum , lsum , rsum , mx , down ; int n, root, tot; bool f , ok; queue<int> q; void init(int x){ if(!x) return ; q.push(x); init(ch[x][0]); init(ch[x][1]); ch[x][0] = ch[x][1] = 0; sum[x] = lsum[x] = rsum[x] = -inf; } int creat(int v, int fa){ int x = q.front(); q.pop(); pre[x] = fa; ch[x][0] = ch[x][1] = 0; val[x] = sum[x] = v; mx[x] = lsum[x] = rsum[x] = v; sz[x] = 1; down[x] = inf; f[x] = 0; return x; } void push_up(int x){ int lx = ch[x][0], rx = ch[x][1]; sz[x] = sz[lx] + sz[rx] + 1; sum[x] = sum[lx] + sum[rx] + val[x]; lsum[x] = max(lsum[lx], sum[lx] + max(0, lsum[rx]) + val[x]); rsum[x] = max(rsum[rx], sum[rx] + max(0, rsum[lx]) + val[x]); mx[x] = max(0, rsum[lx]) + max(0, lsum[rx]) + val[x]; mx[x] = max(mx[x], max(mx[lx], mx[rx])); } void push_lazy(int x, int v){ sum[x] = sz[x] * v; val[x] = v; mx[x] = lsum[x] = rsum[x] = max(v, sum[x]); down[x] = v; } void push_down(int x){ if(f[x]){ swap(ch[x][0], ch[x][1]); if(ch[x][0]) f[ch[x][0]] ^= 1, swap(lsum[ch[x][0]], rsum[ch[x][0]]); if(ch[x][1]) f[ch[x][1]] ^= 1, swap(lsum[ch[x][1]], rsum[ch[x][1]]); f[x] = 0; } if(down[x] != inf){ if(ch[x][0]) push_lazy(ch[x][0], down[x]); if(ch[x][1]) push_lazy(ch[x][1], down[x]); down[x] = inf; } } int build(int ll, int rr, int fa){ if(ll > rr) return 0; int x = creat(a[md], fa); ch[x][0] = build(ll, md - 1, x); ch[x][1] = build(md + 1, rr, x); push_up(x); return x; } void rotate(int x){ int y = pre[x], d = ch[y][1] == x; ch[y][d] = ch[x][!d]; if(ch[x][!d]) pre[ch[x][!d]] = y; ch[x][!d] = y; pre[x] = pre[y]; pre[y] = x; if(pre[x]) ch[pre[x]][ch[pre[x]][1] == y] = x; push_up(y); } void P(int x){ if(pre[x]) P(pre[x]); push_down(x); } void splay(int x, int goal){ P(x); while(pre[x] != goal){ int fa = pre[x], ff = pre[fa]; if(ff == goal) rotate(x); else if((ch[ff][1] == fa) == (ch[fa][1] == x)) rotate(fa), rotate(x); else rotate(x), rotate(x); } push_up(x); if(goal == 0) root = x; } int Kth(int k){ int x = root; while(x){ push_down(x); if(sz[ch[x][0]] >= k) x = ch[x][0]; else{ k -= sz[ch[x][0]] + 1; if(k == 0) return x; x = ch[x][1]; } } return x; } void output(int x){ if(!x) return ; push_down(x); output(ch[x][0]); if(val[x] < inf){ if(!ok) ok = 1; else printf(" "); printf("%d", val[x]); } output(ch[x][1]); } void Insert(int k, int cnt){ splay(Kth(k+1), 0); splay(Kth(k+2), root); int fa = ch[root][1]; ch[fa][0] = build(1, cnt, fa); push_up(fa); push_up(root); } void Delete(int L, int R){ splay(Kth(L), 0); splay(Kth(R+2), root); int fa = ch[root][1]; init(ch[fa][0]); ch[fa][0] = 0; push_up(fa); push_up(root); } void Makesame(int L, int R, int c){ splay(Kth(L), 0); splay(Kth(R+2), root); int fa = ch[root][1]; push_lazy(ch[fa][0], c); push_up(fa); push_up(root); } int main(){ int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= 700000; ++i) q.push(i); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); a[0] = a[n+1] = -inf; sum[0] = 0; lsum[0] = rsum[0] = mx[0] = -inf; root = build(0, n + 1, 0); char s[20]; int cur, cnt, c; while(m--){ scanf("%s", s); if(s[0] == 'I'){ scanf("%d%d", &cur, &cnt); for(int i = 1; i <= cnt; ++i) scanf("%d", &a[i]); Insert(cur, cnt); n += cnt; // output(root); puts(""); } else if(s[0] == 'D'){ scanf("%d%d", &cur, &cnt); Delete(cur, cur + cnt - 1); n -= cnt; // output(root); puts(""); } else if(s[0] == 'M' && s[2] == 'K'){ scanf("%d%d%d", &cur, &cnt, &c); Makesame(cur, cur + cnt - 1, c); } else if(s[0] == 'R'){ scanf("%d%d", &cur, &cnt); int L = cur, R = cur + cnt - 1; splay(Kth(L), 0); splay(Kth(R+2), root); int fa = ch[root][1]; int x = ch[fa][0]; f[x] ^= 1; swap(lsum[x], rsum[x]); } else if(s[0] == 'G'){ scanf("%d%d", &cur, &cnt); int L = cur, R = cur + cnt - 1; splay(Kth(L), 0); splay(Kth(R+2), root); int fa = ch[root][1]; printf("%d\n", sum[ch[fa][0]]); } else{ int L = 1, R = n; splay(Kth(L), 0); splay(Kth(R+2), root); int fa = ch[root][1]; printf("%d\n", mx[ch[fa][0]]); } } return 0; }
相关文章推荐
- 通过SQL case when语法实现统计SQL的纵表转横向
- OC中的遍历与排序
- 【Mysql错误】Unable to connect to remote host. Catalog download has failed.
- 精简代码示例展示Android中MVP模式
- 第三周项目3—随机数函数应用于游戏
- SciTE: The Notepad++ for Linux
- hdoj-1128-Self Numbers
- 第五周项目1:三角形类雏形(2)
- eclipse通过jdbc访问mysql数据库
- 周总结3.18
- vim Ctags 安装与使用
- java关键字总结
- 用jekyll和github Pages写博客
- CodeForces 652B z-sort
- 周总结3.26
- 每天一个Linux命令
- swiper去除滑动设置
- Java中常见数据结构:list与map
- MRC&ARC
- ctrl键使提示信息变透明