# NOI2005 维修数列(splay)

204人阅读 评论(0)

#include<cstdio>
#include<cstring>
#include<algorithm>

inline void get(int &r) {
char c, b=0; r=0;
do{c=getchar();if(c=='-')b=1;}while (c<'0'||c>'9');
do{r=r*10+c-'0';c=getchar();}while (c>='0'&&c<='9');
if (b) r = -r;
}

const int MAXN = 500010;
const int inf = 1e9;
using namespace std;
#define lch(x) x->ch[0]
#define rch(x) x->ch[1]

int N, M;
struct Node {
int sz, lmx, rmx, mx, sum, v;
bool rev, sam; //即时生效
Node*fa, *ch[2];
Node () {
lmx = rmx = mx = -inf;
rev = sam = 0;
sum = sz = v = 0;
}
} nil, *NIL = &nil, *r1, *r2, nds[MAXN];
//r1为序列，r2为回收站
int arr[MAXN];

inline void upsm(Node*x, int v)
{
x->v = v;
x->sum = v * x->sz;
x->mx = x->lmx = x->rmx = max(x->sum, v);
x->sam = 1;
}
inline void uprv(Node*x)
{
swap(lch(x), rch(x));
swap(x->lmx, x->rmx);
x->rev ^= 1;
}

inline void pushdown(Node*x)
{
if (x->sam) {
x->sam = x->rev = 0;
if (lch(x) != NIL) upsm(lch(x), x->v);
if (rch(x) != NIL) upsm(rch(x), x->v);
}
if (x->rev) {
x->rev = 0;
if (lch(x) != NIL) uprv(lch(x));
if (rch(x) != NIL) uprv(rch(x));
}
}

inline void pushup(Node*x)
{
Node*&L = lch(x), *&R = rch(x);
x->sz = L->sz + R->sz + 1;
x->sum = L->sum + R->sum + x->v;
x->lmx = max(L->lmx, L->sum + x->v + max(R->lmx, 0));
x->rmx = max(R->rmx, R->sum + x->v + max(L->rmx, 0));
x->mx = max(0, L->rmx) + x->v + max(0, R->lmx);
x->mx = max(x->mx, max(L->mx, R->mx));
}

inline void rotate(Node *x)
{
Node *y = x->fa;
int d = (x==lch(y));
pushdown(y), pushdown(x);
y->ch[!d] = x->ch[d];
if (x->ch[d] != NIL) x->ch[d]->fa = y;
x->fa = y->fa;
if (y->fa != NIL)
y->fa->ch[ y->fa->ch[1]==y ] = x;
x->ch[d] = y;
y->fa = x;
pushup(y);
}

void splay(Node*&r, Node*x, Node*to=NIL)
{
pushdown(x);
for (Node *y, *z; x->fa != to; rotate(x)) {
y = x->fa; z = y->fa;
if (z != to) rotate((y==lch(z))^(x==lch(y)) ? x : y);
}
pushup(x);
if (to == NIL) r = x;
}

Node* getkth(Node*&r, int k, Node*to=NIL)
{
Node*t = r;
pushdown(t);
for (; k != lch(t)->sz + 1; pushdown(t))
if (k <= lch(t)->sz) t = lch(t);
else k -= lch(t)->sz + 1, t = rch(t);
splay(r, t, to);
return t;
}

void merge(Node*&x, Node*&y) //合并后的树保存在x中
{
getkth(x, x->sz);
getkth(y, 1);
rch(x) = y; y->fa = x; pushup(x);
}

Node*build0(int l, int r, Node*fa) //建树并填值
{
if (l > r) return NIL;
int mid = (l+r)>>1;
nds[mid].ch[0] = build0(l, mid-1, &nds[mid]);
nds[mid].ch[1] = build0(mid+1, r, &nds[mid]);
nds[mid].v = nds[mid].sum = arr[mid];
nds[mid].fa = fa;
pushup(&nds[mid]);
return &nds[mid];
}

void build1(Node*t, int k) //将已建好的二叉树填上值
{
if (t==NIL) return;
build1(lch(t), k);
build1(rch(t), k+1 + lch(t)->sz);
t->v = arr[k + lch(t)->sz + 1];
t->sam = t->rev = 0;
pushup(t);
}

int qsum(int pos, int tot)
{
getkth(r1, pos);
getkth(r1, pos + tot + 1, r1);
pushdown(rch(r1)->ch[0]);
return rch(r1)->ch[0]->sum;
}

int qmax()
{
int cnt = r1->sz;
getkth(r1, 1), getkth(r1, cnt, r1);
pushdown(rch(r1)->ch[0]);
return rch(r1)->ch[0]->mx;
}

void insert(int pos, int tot)
{
for (int i = 1; i<=tot; ++i) get(arr[i]);
r2 = getkth(r2, tot + 1);
Node*t = r2->ch[0];
build1(t, 0);
getkth(r1, pos+1);
getkth(r1, pos+2, r1);
r1->ch[1]->ch[0] = t;
t->fa = rch(r1);
r2->ch[0] = NIL;
pushup(r2);
pushup(rch(r1)); pushup(r1);
}

void erase(int pos, int tot)
{
getkth(r1, pos);
getkth(r1, pos+tot+1, r1);
Node*t = rch(r1)->ch[0];
rch(r1)->ch[0] = NIL;
t->fa = NIL;
merge(r2, t);
pushup(rch(r1)); pushup(r1);
}

void makesame(int pos, int tot, int c)
{
getkth(r1, pos);
getkth(r1, pos+tot+1, r1);
Node*&t = rch(r1)->ch[0];
upsm(t, c);
pushdown(rch(r1));
pushup(rch(r1)); pushup(r1);
}

void reverse(int pos, int tot)
{
getkth(r1, pos);
getkth(r1, pos+tot+1, r1);
uprv(lch(rch(r1)));
pushdown(rch(r1));
pushup(rch(r1)); pushup(r1);
}

int main()
{
nil.ch[0] = nil.ch[1] = nil.fa = NIL;
get(N), get(M);
for (int i = 1; i<=N; ++i) get(arr[i]);
r1 = build0(0, N+1, NIL);
r2 = build0(N+2, MAXN-2, NIL);
char op[99];
int a, b, c;
for (int i = 1; i<=M; ++i) {
scanf("%s", op);
if (op[0] == 'I')
get(a), get(b), insert(a, b);
else if (op[0] == 'D')
get(a), get(b), erase(a, b);
else if (op[2] == 'K')
get(a), get(b), get(c), makesame(a, b, c);
else if (op[0] == 'R')
get(a), get(b), reverse(a, b);
else if (op[0] == 'G')
get(a), get(b), printf("%d\n", qsum(a, b));
else printf("%d\n", qmax());
}
return 0;
}


0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：45104次
• 积分：1429
• 等级：
• 排名：千里之外
• 原创：98篇
• 转载：0篇
• 译文：0篇
• 评论：4条
友情链接
阅读排行
最新评论