您的位置:首页 > 其它

bzoj:1500: [NOI2005]维修数列

2016-02-29 17:57 357 查看

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





[b]总算切掉了这SPLAY神题……[/b]

[b]主要就是得每次挪个根,把要操作的区间卡成一颗完整的子树就好啦![/b]

[b]细节还是调了挺久…= =…没办法,弱嘛...>_<[/b]

[b]一开始以为回收空间会很麻烦,结果还是开个queue把删掉的节点遍历一遍放进去就完了。[/b]

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

queue <int> qh;
int n,m,l,r,p,ch,a[500000],pos,tot,u,c,f;
inline int read(){
p=0;ch=getchar();f=1;
while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') p=p*10+ch-48,ch=getchar();
return p*f;
}
struct tree{
int l,r,k,f,s,c,sum,lx,rx,mx;
bool bo;
tree(){
bo=f=l=r=sum=0;
c=1001;
}
};
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
struct splay_tree{
int size,root;
tree t[500001];
splay_tree(){
size=0;root=0;
}
inline void update(int p){
t[p].s=t[t[p].l].s+t[t[p].r].s+1;
t[p].sum=t[p].k+t[t[p].l].sum+t[t[p].r].sum;
t[p].lx=max(t[t[p].l].lx,t[t[p].r].lx+t[t[p].l].sum+t[p].k);
t[p].rx=max(t[t[p].r].rx,t[t[p].l].rx+t[t[p].r].sum+t[p].k);
t[p].mx=max(max(t[t[p].l].mx,t[t[p].r].mx),t[t[p].l].rx+t[t[p].r].lx+t[p].k);
}
inline void pd(int x){
if (t[x].bo){
t[t[x].l].bo^=1;t[t[x].r].bo^=1;
swap(t[x].l,t[x].r);
swap(t[x].lx,t[x].rx);
t[x].bo=0;
}
if (t[x].c!=1001){
t[x].k=t[x].c;
t[t[x].l].c=t[t[x].r].c=t[x].c;
t[x].sum=t[x].c*t[x].s;
if (t[x].c>=0) t[x].lx=t[x].rx=t[x].mx=t[x].sum;else t[x].lx=t[x].rx=0,t[x].mx=t[x].c;
t[x].c=1001;
}
}
inline void ler(int &p){
int k=t[p].r;
t[k].f=t[p].f;
t[p].f=k;
t[t[k].l].f=p;
t[p].r=t[k].l;
t[k].l=p;
update(p);update(k);
p=k;
}
inline void rir(int &p){
int k=t[p].l;
t[k].f=t[p].f;
t[p].f=k;
t[t[k].r].f=p;
t[p].l=t[k].r;
t[k].r=p;
update(p);update(k);
p=k;
}
inline void ph(int &p,bool bo){
if (bo) rir(p);else ler(p);
}
inline bool gc(int p){return t[t[p].f].l==p;}
inline void rot(int p){
if (t[p].f==root) ph(root,gc(p));else
if (gc(t[p].f)) ph(t[t[t[p].f].f].l,gc(p));else ph(t[t[t[p].f].f].r,gc(p));
}
inline void splay(int p,int f){
while(t[p].f!=f){
if (t[t[p].f].f==f) rot(p);else
if (gc(t[p].f)==gc(p)) rot(t[p].f),rot(p);else rot(p),rot(p);
}
}
inline void build(int &p,int l,int r){
if (l>r) return;
if (!qh.empty()) p=qh.front(),qh.pop();else p=++size;
int mid=(l+r)>>1;
t[p].k=a[mid];
build(t[p].l,l,mid-1);
build(t[p].r,mid+1,r);
t[t[p].l].f=t[t[p].r].f=p;
if (l==r){
t[p].sum=a[mid];
if (a[mid]>=0) t[p].lx=t[p].rx=a[mid];else t[p].lx=t[p].rx=0;
t[p].mx=a[mid];
t[p].s=1;
}else update(p);
}
inline int find(int x,int y){
pd(x);
pd(t[x].l);pd(t[x].r);update(x);
if (t[t[x].l].s<y-1) return find(t[x].r,y-1-t[t[x].l].s);
if (t[t[x].l].s==y-1) return x;
return find(t[x].l,y);
}
inline void in(int x,int n){
u=find(root,x+2);x=find(root,x+1);
splay(x,0);splay(u,x);
build(t[u].l,1,n);
t[t[u].l].f=u;
update(u);update(x);
}
inline void reuse(int x){
if (!x) return;
qh.push(x);
reuse(t[x].l);reuse(t[x].r);
t[x].l=t[x].r=t[x].bo=0;t[x].c=1001;
}
inline void del(int x,int n){
u=find(root,x);x=find(root,x+n+1);
splay(u,0);splay(x,u);
reuse(t[x].l);
t[x].l=0;
update(x);update(u);
}
inline void change(int x,int n,int c){
u=find(root,x);x=find(root,x+n+1);
splay(u,0);splay(x,u);
t[t[x].l].c=c;
pd(t[x].l);
update(x);update(u);
}
inline void turn(int x,int n){
u=find(root,x);x=find(root,x+n+1);
splay(u,0);splay(x,u);
t[t[x].l].bo^=1;
pd(t[x].l);
update(x);update(u);
}
inline int qu(int x,int n){
u=find(root,x);x=find(root,x+n+1);
splay(u,0);splay(x,u);
return t[t[x].l].sum;
update(x);update(u);
}
}t;
char ss[20];
int main(){
register int i;
n=read();m=read();
for (i=1;i<=n;i++) a[i]=read();
a[0]=-1e8;a[n+1]=-1e8;
t.build(t.root,0,n+1);
while(m--)
{
scanf("%s",ss);
if (ss[0]=='I'){
pos=read();tot=read();
for (i=1;i<=tot;i++) a[i]=read();
t.in(pos,tot);
}else if (ss[0]=='D') pos=read(),tot=read(),t.del(pos,tot);
else if (ss[0]=='M'){
if (ss[2]=='K') pos=read(),tot=read(),c=read(),t.change(pos,tot,c);
else printf("%d\n",t.t[t.root].mx);
}else if (ss[0]=='R') pos=read(),tot=read(),t.turn(pos,tot);
else if (ss[0]=='G') pos=read(),tot=read(),printf("%d\n",t.qu(pos,tot));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: