BZOJ-1500 [NOI2005]维修数列
神级数据结构维护题。。。Splay练手题。
#include <cstdlib> #include <cstdio> #include <cstring> #include <cctype> #include <algorithm> #include <iostream> #include <queue> #define rep(i, l, r) for(int i=l; i<=r; i++) #define clr(x, c) memset(x, c, sizeof(x)) #define inf 1000000000 #define maxn 1000005 using namespace std; inline int read() { int x=0, f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*f; } int c[maxn][2], h[maxn], size[maxn], sum[maxn], ls[maxn], rs[maxn], ms[maxn], v[maxn], rt, id[maxn], a[maxn]; int cnt; char s[10]; bool rev[maxn], tag[maxn]; queue <int> q; inline void update(int x) { int l=c[x][0], r=c[x][1]; sum[x]=sum[l]+sum[r]+v[x]; size[x]=size[l]+size[r]+1; ms[x]=max(ms[l], ms[r]); ms[x]=max(ms[x], rs[l]+v[x]+ls[r]); ls[x]=max(ls[l], sum[l]+v[x]+ls[r]); rs[x]=max(rs[r], rs[l]+v[x]+sum[r]); } void pushdown(int x) { int l=c[x][0], r=c[x][1]; if (tag[x]) { rev[x]=tag[x]=0; if (l) tag[l]=1, v[l]=v[x], sum[l]=v[l]*size[l]; if (r) tag[r]=1, v[r]=v[x], sum[r]=v[r]*size[r]; if (v[x]>=0) { if (l) ls[l]=rs[l]=ms[l]=sum[l]; if (r) ls[r]=rs[r]=ms[r]=sum[r]; } else { if (l) ls[l]=rs[l]=0, ms[l]=v[l]; if (r) ls[r]=rs[r]=0, ms[r]=v[r]; } } if (rev[x]) { rev[x]^=1; rev[l]^=1; rev[r]^=1; swap(ls[l], rs[l]); swap(ls[r], rs[r]); swap(c[l][0], c[l][1]); swap(c[r][0], c[r][1]); } } inline void rotate(int x, int &k) { int y=h[x], z=h[y], l=(c[y][1]==x), r=l^1; if (y==k) k=x; else c[z][c[z][1]==y]=x; h[c[x][r]]=y, h[y]=x, h[x]=z; c[y][l]=c[x][r]; c[x][r]=y; update(y), update(x); } inline void Splay(int x, int &k) { /* while (x!=k) { int y=h[x], z=h[y]; if (y!=k) { (c[y][0]==x)^(c[z][0]==y) ? rotate(x, k) : rotate(y, k); } rotate(x, k); } */ while (x!=k) rotate(x, k); } int Find(int x, int k) { pushdown(x); int l=c[x][0], r=c[x][1]; if (size[l]+1==k) return x; if (size[l]>=k) return Find(l, k); return Find(r, k-size[l]-1); } void Del(int x) { if (!x) return; int l=c[x][0], r=c[x][1]; Del(l); Del(r); q.push(x); h[x]=c[x][0]=c[x][1]=0; tag[x]=rev[x]=0; } inline int Split(int k, int n) { int x=Find(rt, k), y=Find(rt, k+n+1); Splay(x, rt); Splay(y, c[x][1]); return c[y][0]; } inline void QSum(int k, int n){int x=Split(k, n); printf("%d\n", sum[x]);} inline void Same(int k, int n, int val) { int x=Split(k, n), y=h[x]; v[x]=val; tag[x]=1; sum[x]=size[x]*val; if (val>=0) ls[x]=rs[x]=ms[x]=sum[x]; else ls[x]=rs[x]=0, ms[x]=val; update(y), update(h[y]); } inline void Rever(int k, int n) { int x=Split(k, n), y=h[x]; if (tag[x]) return; rev[x]^=1; swap(c[x][0], c[x][1]); swap(ls[x], rs[x]); update(y), update(h[y]); } inline void Delete(int k, int n) { int x=Split(k, n), y=h[x]; Del(x); c[y][0]=0; update(y), update(h[y]); } void Build(int l, int r, int f) { if (l>r) return; int mid=(l+r)>>1, now=id[mid], last=id[f]; if (l==r) { sum[now]=a[l], size[now]=1, tag[now]=rev[now]=0; if (a[l]>=0) ls[now]=rs[now]=ms[now]=a[l]; else ls[now]=rs[now]=0, ms[now]=a[l]; } else Build(l, mid-1, mid), Build(mid+1, r, mid); v[now]=a[mid], h[now]=last, update(now); c[last][mid>f]=now; } inline void Insert(int k, int n) { rep(i, 1, n) a[i]=read(); rep(i, 1, n) if (!q.empty()) id[i]=q.front(), q.pop(); else id[i]=++cnt; Build(1, n, 0); int x=Find(rt, k+1), y=Find(rt, k+2), z=id[(1+n)>>1]; Splay(x, rt); Splay(y, c[x][1]); h[z]=y, c[y][0]=z; update(y), update(x); } int main() { int n=read(), m=read(); ms[0]=a[1]=a[n+2]=-inf; rep(i, 1, n) a[i+1]=read(); rep(i, 1, n+2) id[i]=i; Build(1, n+2, 0); rt=(n+3)>>1, cnt=n+2; rep(i, 1, m) { scanf("%s", s); if (s[0]=='I') {int a=read(), b=read(); Insert(a, b);} else if (s[0]=='D') {int a=read(), b=read(); Delete(a, b);} else if (s[0]=='R') {int a=read(), b=read(); Rever(a, b);} else if (s[0]=='G') {int a=read(), b=read(); QSum(a, b);} else if (s[2]=='K') {int a=read(), b=read(); Same(a, b, read());} else printf("%d\n", ms[rt]); } return 0; }