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;
}

浙公网安备 33010602011771号