您的位置:首页 > 其它

[bzoj1500][NOI2005 维修数列] (splay区间操作)

2017-01-08 09:24 519 查看

Description



Input

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。

第2行包含N个数字,描述初始时的数列。

以下M行,每行一条命令,格式参见问题描述中的表格。

任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。

插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

Output

对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

Sample Input

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM


Sample Output

-1
10
1
10


HINT



Solution

#include<cstdio>
#include<iostream>
#define N 500010
#define inf 0x3f3f3f3f
#define mid ((x>>1)+(y>>1)+(x&y&1))
using namespace std;
inline int Rin(){
int x=0,c=getchar(),f=1;
for(;c<48||c>57;c=getchar())
if(!(c^45))f=-1;
for(;c>47&&c<58;c=getchar())
x=(x<<1)+(x<<3)+c-48;
return x*f;
}
struct nt{
nt*ch[2],*p;
bool rev;int cov;
int size,sum,v,lmx,rmx,mmx;
bool d(){return this==p->ch[1];}
void setc(nt*c,int d){
ch[d]=c;
c->p=this;
}
void revIt(){
rev^=1;
swap(lmx,rmx);
swap(ch[0],ch[1]);
}
void covIt(int co){
cov=v=co;
sum=co*size;
co>0?lmx=rmx=mmx=sum:
lmx=rmx=mmx=co;
}
void pu(){
size=1+ch[0]->size+ch[1]->size;
sum=v+ch[0]->sum+ch[1]->sum;
lmx=max(ch[0]->lmx,ch[0]->sum+v+max(ch[1]->lmx,0));
rmx=max(ch[1]->rmx,ch[1]->sum+v+max(ch[0]->rmx,0));
mmx=max(max(ch[0]->mmx,ch[1]->mmx),max(ch[0]->rmx,0)+v+max(ch[1]->lmx,0));
}
void relax(){
if(rev)
ch[0]->revIt(),
ch[1]->revIt();
if(cov^inf)
ch[0]->covIt(cov),
ch[1]->covIt(cov);
rev=0;
cov=inf;
}
};
nt*null=new nt();
nt*root=null;
int n,a
,m;
char sign[10];
nt*newnode(nt*p,int v){
nt*o=new nt();
o->size=1;
o->v=o->sum=o->lmx=o->rmx=o->mmx=v;
o->ch[0]=o->ch[1]=null;
o->cov=inf;
o->p=p;
return o;
}
void rot(nt*&o){
nt*p=o->p;
p->relax();
o->relax();
bool d=o->d();
p->p->setc(o,p->d());
p->setc(o->ch[!d],d);
o->setc(p,!d);
p->pu();o->pu();
if(p==root)root=o;
}
void splay(nt*o,nt*p){
while(o->p!=p)
if(o->p->p==p)
rot(o);
else
o->d()^o->p->d()?(rot(o),rot(o)):(rot(o->p),rot(o));
o->pu();
}
nt*build(int x,int y){
if(x>y)return null;
nt*o=newnode(o,a[mid]);
o->setc(build(x,mid-1),0);
o->setc(build(mid+1,y),1);
o->pu();
return o;
}
void del(nt*&o){
if(o->ch[0]!=null)del(o->ch[0]);
if(o->ch[1]!=null)del(o->ch[1]);
delete o;
}
nt*kth(int k){
for(nt*o=root;;){
o->relax();
if(k<=o->ch[0]->size)
o=o->ch[0];
else{
k-=o->ch[0]->size+1;
if(!k)return o;
o=o->ch[1];
}
}
}
int main(){
n=Rin(),m=Rin();
for(int i=1;i<=n;i++)a[i]=Rin();
root=build(0,n+1);
root->p=null;
int x,y,z;
while(m--){
scanf("%s",sign);
switch(sign[2]){
case'S':
x=Rin(),y=Rin();
for(int i=1;i<=y;i++)a[i]=Rin();
splay(kth(x+1),null);
splay(kth(x+2),root);
root->ch[1]->setc(build(1,y),0);
root->ch[1]->pu();
root->pu();
break;
case'L':
x=Rin(),y=Rin();
splay(kth(x),null);
splay(kth(x+y+1),root);
del(root->ch[1]->ch[0]);
root->ch[1]->ch[0]=null;
root->ch[1]->pu();
root->pu();
break;
case'K':
x=Rin(),y=Rin(),z=Rin();
splay(kth(x),null);
splay(kth(x+y+1),root);
root->ch[1]->ch[0]->covIt(z);
root->ch[1]->pu();
root->pu();
break;
case'T':
x=Rin(),y=Rin();
splay(kth(x),null);
splay(kth(x+y+1),root);
printf("%d\n",root->ch[1]->ch[0]->sum);
break;
case'V':
x=Rin(),y=Rin();
splay(kth(x),null);
splay(kth(x+y+1),root);
root->ch[1]->ch[0]->revIt();
root->ch[1]->pu();
root->pu();
break;
case'X':
splay(kth(1),null);
splay(kth(root->size),root);
printf("%d\n",root->ch[1]->ch[0]->mmx);
break;
default:break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: