初看这道题,被吓到了....
思路就不多说了,已经很多人研究过这道题。
参考的博客:
https://www.byvoid.com/blog/noi-2005-sequence/
http://www.cnblogs.com/kuangbin/archive/2013/08/28/3287822.html
<pre name="code" class="cpp">#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 5e5+10;
const int inf = 1e8+1000;
#define Key_val root->c[1]->c[0]
struct Snode
{
Snode *p,*c[2];
int key,sz,num,sum,mx,lx,rx;
bool rev,same;
bool getlr(){return p->c[1]==this;}
Snode *link(int w,Snode *x,Snode *null){c[w]=x;if(x!=null)x->p=this;return this;}
}S[maxn],*root,*null,*lb,*rb;
int sa[maxn],tot1,tot2;
int a[maxn];
int n,q;
Snode *NewNode(int key, Snode *p)
{
int r;
if(tot2) r = sa[tot2--];
else r = ++tot1;
Snode *e = S+r;
e->p = p;
e->sz = e->num = 1;
e->key = e->sum = e->mx = e->lx = e->rx = key;
e->same = e->rev = false;
e->c[0] = e->c[1] = null;
return e;
}
void Updata_same(Snode *x, int v)
{
if(x == null) return;
x->same = 1; x->key = v;
x->sum = v*x->sz;
x->lx = x->rx = x->mx = max(v, x->sum);
}
void Updata_rev(Snode *x)
{
if(x == null) return;
swap(x->c[0], x->c[1]);
swap(x->lx, x->rx);
x->rev ^= 1;
}
void pushdown(Snode *x)
{
if(x == null) return;
if(x->same)
{
Updata_same(x->c[0], x->key);
Updata_same(x->c[1], x->key);
x->same = 0;
}
if(x->rev)
{
Updata_rev(x->c[0]);
Updata_rev(x->c[1]);
x->rev = 0;
}
}
void pushup(Snode *x)
{
if(x == null) return;
Snode *ls = x->c[0], *rs = x->c[1];
x->sz = ls->sz + rs->sz + x->num;
x->sum = ls->sum + rs->sum + x->key;
x->lx = max(ls->lx, ls->sum + x->key + max(0, rs->lx));
x->rx = max(rs->rx, rs->sum + x->key + max(0, ls->rx));
x->mx = max(0, ls->rx) + x->key + max(0, rs->lx);
x->mx = max(x->mx, max(ls->mx, rs->mx));
}
void dfs(Snode *x)
{
if(x == null) return;
///pushdown(x);
dfs(x->c[0]);
printf("%d sz:%d sum:%d\n",x->key,x->sz,x->sum);
dfs(x->c[1]);
}
void test()
{
dfs(root);
puts("");
}
Snode* Build(int l,int r,Snode *p)
{
if(l > r) return null;
int mid = (l+r)/2;
Snode *x = NewNode(a[mid], p);
x->c[0] = Build(l,mid-1,x);
x->c[1] = Build(mid+1,r,x);
pushup(x);
return x;
}
void rot(Snode *x)
{
Snode *q = x->p->p;
int o = x->getlr();
x->link(!o,x->p->link(o,x->c[!o],null),null);
pushup(x->p);
if(q!=null) q->link(q->c[1]==x->p, x,null);
else {x->p=null; root=x;}
}
void splay(Snode *x,Snode *tar)
{
pushdown(x);///这是要加上的...
while(x->p!=tar && x->p->p!=tar)
{
pushdown(x->p->p);
pushdown(x->p);
pushdown(x);
x->getlr()==x->p->getlr()?rot(x->p):rot(x),rot(x);
}
if(x->p!=tar)
{
pushdown(x->p);
pushdown(x);
rot(x);
}
pushup(x);
}
#define lsz x->c[0]->sz
void select(int k, Snode *y)
{
Snode *x = root;
pushdown(x);
while(!(lsz < k && lsz + x->num >= k))
{
if(k <= lsz)
x = x->c[0];
else
{
k -= lsz + x->num;
x = x->c[1];
}
pushdown(x);
}
splay(x, y);
}
void Insert(int pos,int tot)
{
for(int i=0;i<tot;i++) scanf("%d",&a[i]);
select(pos+1,null);
select(pos+2,root);
Key_val=Build(0,tot-1,root->c[1]);
pushup(root->c[1]);
pushup(root);
}
void earse(Snode *x)
{
if(x==null) return;
sa[++tot2] = x-S;
earse(x->c[0]);
earse(x->c[1]);
}
void Delete(int pos,int tot)
{
select(pos,null);
select(pos+tot+1,root);
earse(Key_val);
Key_val = null;
splay(root->c[1],null);
}
void Reverse(int pos,int tot)
{
select(pos,null);
select(pos+tot+1,root);
Updata_rev(Key_val);
splay(Key_val,null);
}
void MakeSame(int pos,int tot,int value)
{
select(pos,null);
select(pos+tot+1,root);
Updata_same(Key_val, value);
splay(Key_val,null);
}
int GetSum(int pos, int tot)
{
select(pos, null);
select(pos+tot+1, root);
return Key_val->sum;
}
int MaxSum()
{
return root->mx;
}
void init()
{
tot1 = tot2 = 0;
null = NewNode(-inf, 0);
null->c[0] = null->c[1] = null;
lb = root = NewNode(-inf, null);
rb = root->c[1] = NewNode(-inf, root);
null->sz = 0;
null->sum = lb->sum = rb->sum = 0;
pushup(root);
}
int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
init();
Insert(0,n);
char op[20];
int x,y,z;
while(q--)
{
scanf("%s",op);
if(op[0]=='I')
{
scanf("%d%d",&x,&y);
Insert(x,y);
}
else if(op[0]=='D')
{
scanf("%d%d",&x,&y);
Delete(x,y);
}
else if(op[2]=='K')
{
scanf("%d%d%d",&x,&y,&z);
MakeSame(x,y,z);
}
else if(op[0]=='R')
{
scanf("%d%d",&x,&y);
Reverse(x,y);
}
else if(op[0]=='G')
{
scanf("%d%d",&x,&y);
printf("%d\n",GetSum(x,y));
}
else if(op[2]=='X')
printf("%d\n",MaxSum());
}
}
return 0;
}
///因为被一道题卡了内存(估计原因是在那个oj里面,指针是8个字节),写了一个用数组的,当模板用。。。2015.02.18
<pre name="code" class="cpp">#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 5e5+10;
const int inf = 1e8+1000;
#define ls c[x][0]
#define rs c[x][1]
#define Key_val c[c[root][1]][0]
int p[maxn],c[maxn][2],root;
int key[maxn],sz[maxn],num[maxn],sum[maxn];
int mx[maxn],lx[maxn],rx[maxn];
bool rev[maxn],same[maxn];
int a[maxn],pool[maxn],tot1,tot2;
int n,q;
bool getlr(int r){return c[p[r]][1]==r;}
int link(int r,int w,int x){c[r][w]=x;if(x)p[x]=r;return r;}
void NewNode(int &r,int v,int per)
{
if(tot2) r = pool[tot2--];
else r = ++tot1;
p[r] = per;
sz[r] = num[r] = 1;
key[r] = sum[r] = mx[r] = lx[r] = rx[r] = v;
same[r] = rev[r] = 0;
c[r][0] = c[r][1] = 0;
}
void Updata_same(int x,int v)
{
if(!x) return;
same[x] = 1; key[x] = v;
sum[x] = v*sz[x];
lx[x] = rx[x] = mx[x] = max(v, sum[x]);
}
void Updata_rev(int x)
{
if(!x) return;
swap(ls,rs);
swap(lx[x],rx[x]);
rev[x] ^= 1;
}
void pushup(int x)
{
sz[x] = sz[ls] + sz[rs] + num[x];
sum[x] = sum[ls] + sum[rs] + key[x];
lx[x] = max(lx[ls], sum[ls] + key[x] + max(0, lx[rs]));
rx[x] = max(rx[rs], sum[rs] + key[x] + max(0, rx[ls]));
mx[x] = max(0, rx[ls]) + key[x] + max(0, lx[rs]);
mx[x] = max(mx[x], max(mx[ls], mx[rs]));
}
void pushdown(int x)
{
if(same[x])
{
Updata_same(ls, key[x]);
Updata_same(rs, key[x]);
same[x] = 0;
}
if(rev[x])
{
Updata_rev(ls);
Updata_rev(rs);
rev[x] = 0;
}
}
void dfs(int x)
{
if(!x) return;
pushdown(x);
dfs(ls);
printf("%d sz:%d sum:%d\n",key[x],sz[x],sum[x]);
dfs(rs);
}
void test()
{
dfs(root);
puts("");
}
void Build(int &x,int l,int r,int per)
{
if(l > r) return;
int mid = (l+r)/2;
NewNode(x, a[mid], per);
Build(ls,l,mid-1,x);
Build(rs,mid+1,r,x);
pushup(x);
}
void rot(int x)
{
int z = p[p[x]], o = getlr(x);
link(x,!o,link(p[x],o,c[x][!o]));
pushup(p[x]);
if(z) link(z,c[z][1]==p[x],x);
else p[x]=0, root=x;
}
void splay(int x,int tar)
{
pushdown(x);
while(p[x]!=tar)
{
if(p[p[x]]!=tar)pushdown(p[p[x]]);
pushdown(p[x]);
pushdown(x);
if(p[p[x]]!=tar)getlr(x)==getlr(p[x])?rot(p[x]):rot(x);
rot(x);
}
pushup(x);
}
void select(int k, int tar)
{
int x = root;
pushdown(x);
while(!(sz[ls]<k && sz[ls] + num[x] >= k))
{
if(k <= sz[ls])
x = ls;
else
{
k -= sz[ls] + num[x];
x = rs;
}
pushdown(x);
}
splay(x, tar);
}
void Insert(int pos,int tot)
{
for(int i=0;i<tot;i++) scanf("%d",&a[i]);
select(pos+1,0);
select(pos+2,root);
Build(Key_val,0,tot-1,c[root][1]);
splay(Key_val,0);
}
void earse(int x)
{
if(!x) return;
pool[++tot2] = x;
earse(ls);
earse(rs);
}
void Delete(int pos,int tot)
{
select(pos,0);
select(pos+tot+1,root);
earse(Key_val);
Key_val = 0;
splay(c[root][1], 0);
}
void Reverse(int pos,int tot)
{
select(pos,0);
select(pos+tot+1,root);
Updata_rev(Key_val);
splay(Key_val,0);
}
void MakeSame(int pos,int tot,int v)
{
select(pos,0);
select(pos+tot+1,root);
Updata_same(Key_val, v);
splay(Key_val,0);
}
int GetSum(int pos,int tot)
{
select(pos,0);
select(pos+tot+1, root);
return sum[Key_val];
}
int MaxSum()
{
return mx[root];
}
void init()
{
root = tot1 = tot2 = 0;
lx[0] = rx[0] = mx[0] = -inf;
NewNode(root,-inf,0);
NewNode(c[root][1],-inf,root);
pushup(root);
}
int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
init();
Insert(0,n);
char op[20];
int x,y,z;
while(q--)
{
scanf("%s",op);
if(op[0]=='I')
{
scanf("%d%d",&x,&y);
Insert(x,y);
}
else if(op[0]=='D')
{
scanf("%d%d",&x,&y);
Delete(x,y);
}
else if(op[2]=='K')
{
scanf("%d%d%d",&x,&y,&z);
MakeSame(x,y,z);
}
else if(op[0]=='R')
{
scanf("%d%d",&x,&y);
Reverse(x,y);
}
else if(op[0]=='G')
{
scanf("%d%d",&x,&y);
printf("%d\n",GetSum(x,y));
}
else if(op[2]=='X')
printf("%d\n",MaxSum());
}
}
return 0;
}