题目:http://www.spoj.com/problems/GSS6/
题意:给一个长度为n的数组,然后给出Q个4种操作,分别是:删除,插入,替换,查找指定区间连续最大和。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 200005;
const int INF = 1<<28;
int a[N];
struct Node
{
int val,sz;
int sum,ml,mr,mc;
Node *pre,*ch[2];
};
class Splay
{
public:
Node *null,*root,*S[N],data[N];
int cnt,top;
Node *getNewNode(int x)
{
Node *p;
if(top) p = S[top--];
else p = &data[cnt++];
p->val = p->sum = p->ml = p->mr = p->mc = x;
p->sz = 1;
p->ch[0] = p->ch[1] = p->pre = null;
return p;
}
void init()
{
cnt = top = 0;
null = getNewNode(-INF);
null->sum = null->sz = 0;
root = getNewNode(-INF);
root->sum = 0;
root->ch[1] = getNewNode(INF);
root->ch[1]->sum = 0;
root->ch[1]->pre = root;
update(root);
}
void update(Node *p)
{
p->sz = p->ch[0]->sz + p->ch[1]->sz + 1;
p->sum = p->ch[0]->sum + p->ch[1]->sum + p->val;
p->ml = max(p->ch[0]->ml,p->ch[0]->sum + p->val + max(p->ch[1]->ml,0));
p->mr = max(p->ch[1]->mr,p->ch[1]->sum + p->val + max(p->ch[0]->mr,0));
p->mc = max(p->ch[0]->mc,p->ch[1]->mc);
p->mc = max(p->mc,max(p->ch[0]->mr + p->ch[1]->ml,0) + p->val);
p->mc = max(p->mc,max(p->ch[0]->mr,p->ch[1]->ml) + p->val);
}
void rotate(Node *x,int c)
{
Node *y = x->pre;
y->ch[!c] = x->ch[c];
if(x->ch[c] != null)
x->ch[c]->pre = y;
x->pre = y->pre;
if(y->pre != null)
{
if(y->pre->ch[0] == y)
y->pre->ch[0] = x;
else
y->pre->ch[1] = x;
}
x->ch[c] = y;
y->pre = x;
if(y == root)
root = x;
update(y);
}
void splay(Node *x,Node *f)
{
while(x->pre != f)
{
if(x->pre->pre == f)
rotate(x,x->pre->ch[0] == x);
else
{
Node *y = x->pre;
Node *z = y->pre;
if(z->ch[0] == y)
{
if(y->ch[0] == x)
rotate(y,1),rotate(x,1);
else
rotate(x,0),rotate(x,1);
}
else
{
if(y->ch[1] == x)
rotate(y,0),rotate(x,0);
else
rotate(x,1),rotate(x,0);
}
}
}
update(x);
}
void select(int k,Node *f)
{
int tmp;
Node *t = root;
while(true)
{
tmp = t->ch[0]->sz;
if(tmp + 1 == k) break;
if(k <= tmp) t = t->ch[0];
else
{
k -= tmp + 1;
t = t->ch[1];
}
}
splay(t,f);
}
void insert(int pos,int val)
{
Node *tmproot = getNewNode(val);
select(pos-1,null);
select(pos,root);
root->ch[1]->ch[0] = tmproot;
tmproot->pre = root->ch[1];
splay(root->ch[1],null);
}
void del(int k)
{
select(k,null);
Node *old_root = root;
root = root->ch[1];
root->pre = null;
select(1,null);
root->ch[0] = old_root->ch[0];
root->ch[0]->pre = root;
update(root);
S[++top] = old_root;
}
void replace(int x,int y)
{
select(x,null);
root->val = y;
update(root);
}
Node *build(int l,int r)
{
if(l>r) return null;
int m = (l + r) >> 1;
Node *p = getNewNode(a[m]);
p->ch[0] = build(l,m-1);
if(p->ch[0] != null)
p->ch[0]->pre = p;
p->ch[1] = build(m+1,r);
if(p->ch[1] != null)
p->ch[1]->pre = p;
update(p);
return p;
}
};
Splay sp;
int main()
{
char c;
int n,m,x,y;
sp.init();
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
Node *troot = sp.build(1,n);
sp.root->ch[1]->ch[0] = troot;
troot->pre = sp.root->ch[1];
sp.update(sp.root->ch[1]);
sp.update(sp.root);
sp.splay(sp.root->ch[1],sp.null);
scanf("%d",&m);
for(int i = 1; i <= m ; i++)
{
scanf(" %c",&c);
if(c == 'I')
{
scanf("%d %d",&x,&y);
sp.insert(++x,y);
}
else if(c == 'D')
{
scanf("%d",&x);
sp.del(++x);
}
else if(c == 'R')
{
scanf("%d %d",&x,&y);
sp.replace(++x,y);
}
else if(c == 'Q')
{
scanf("%d %d",&x,&y);
sp.select(++x - 1,sp.null);
sp.select(++y + 1,sp.root);
printf("%d\n",sp.root->ch[1]->ch[0]->mc);
}
}
return 0;
}
标签:pre,Node,ch,int,Splay,SPOJ4487,null,root From: https://blog.51cto.com/u_16146153/6388689