记录编号 360820 评测结果 AAAAAAAAAA
题目名称 [NOI 2005]维护数列 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 2.581 s
提交时间 2017-01-01 16:10:46 内存使用 19.38 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#define dir(x) ((int)((x)==(x)->p->ch[1]))
using namespace std;
struct node{
	int data,size,sum,prefix,suffix,maxsum;
	bool rev,same;
	node *ch[2],*p;
	node(int d):data(d),size(1),sum(d),prefix(d),suffix(d),maxsum(d),rev(false),same(false){}
	void reverse(){
		if(data==-1000000)return;
		rev^=true;
		swap(prefix,suffix);
	}
	void makesame(int d){
		if(data==-1000000)return;
		data=d;
		sum=d*size;
		prefix=suffix=maxsum=max(sum,d);
		same=true;
	}
	void pushdown(){
		if(rev){
			ch[0]->reverse();
			ch[1]->reverse();
			swap(ch[0],ch[1]);
			rev=false;
		}
		if(same){
			ch[0]->makesame(data);
			ch[1]->makesame(data);
			same=false;
		}
	}
	void refresh(){
		size=ch[0]->size+ch[1]->size+1;
		sum=ch[0]->sum+ch[1]->sum+data;
		prefix=max(ch[0]->prefix,ch[0]->sum+data+max(ch[1]->prefix,0));
		suffix=max(ch[1]->suffix,ch[1]->sum+data+max(ch[0]->suffix,0));
		maxsum=max(max(ch[0]->maxsum,ch[1]->maxsum),max(ch[0]->suffix,0)+data+max(ch[1]->prefix,0));
	}
}*null=new node(-1000000),*root=null;
void insert(int,int);
void erase(int,int);
void makesame(int,int,int);
void reverse(int,int);
int getsum(int,int);
int maxsum();
node *build(int,int);
void removetree(node*);
node *kth(int);
void splay(node*,node*);
void rot(node*,int);
int n,m,pos,cnt,d,a[5000010];
char c[15];
int main(){
	freopen("seq2005.in","r",stdin);
	freopen("seq2005.out","w",stdout);
	null->ch[0]=null->ch[1]=null->p=null;
	null->size=null->sum=0;
	scanf("%d%d",&n,&m);
	insert(0,n);//dfs(root);
	while(m--){
		scanf("%s",c);
		if(!strcmp(c,"INSERT")){
			scanf("%d%d",&pos,&cnt);
			insert(pos,cnt);
		}
		else if(!strcmp(c,"DELETE")){
			scanf("%d%d",&pos,&cnt);
			erase(pos,cnt);
		}
		else if(!strcmp(c,"MAKE-SAME")){
			scanf("%d%d%d",&pos,&cnt,&d);
			makesame(pos,cnt,d);
		}
		else if(!strcmp(c,"REVERSE")){
			scanf("%d%d",&pos,&cnt);
			reverse(pos,cnt);
		}
		else if(!strcmp(c,"GET-SUM")){
			scanf("%d%d",&pos,&cnt);
			printf("%d\n",getsum(pos,cnt));
		}
		else if(!strcmp(c,"MAX-SUM"))printf("%d\n",maxsum());
	}
	return 0;
}
node *newnode(int d){
	node *x=new node(d);
	x->ch[0]=x->ch[1]=x->p=null;
	return x;
}
void insert(int pos,int cnt){
	for(int i=1;i<=cnt;i++)scanf("%d",&a[i]);
	node *x=build(1,cnt);
	if(root==null){
		root=x;
		return;
	}
	if(!pos){
		splay(kth(1),null);
		root->ch[0]=x;
		x->p=root;
		root->refresh();
	}
	else if(pos==root->size){
		splay(kth(root->size),null);
		root->ch[1]=x;
		x->p=root;
		root->refresh();
	}
	else{
		splay(kth(pos),null);
		splay(kth(pos+1),root);
		root->ch[1]->ch[0]=x;
		x->p=root->ch[1];
		root->ch[1]->refresh();
		root->refresh();
	}
}
void erase(int pos,int cnt){
	if(cnt==root->size){
		removetree(root);
		root=null;
		return;
	}
	if(pos==1){
		splay(kth(cnt+1),null);
		removetree(root->ch[0]);
		root->ch[0]=null;
		root->refresh();
	}
	else if(pos+cnt-1==root->size){
		splay(kth(pos-1),null);
		removetree(root->ch[1]);
		root->ch[1]=null;
		root->refresh();
	}
	else{
		splay(kth(pos-1),null);
		splay(kth(pos+cnt),root);
		removetree(root->ch[1]->ch[0]);
		root->ch[1]->ch[0]=null;
		root->ch[1]->refresh();
		root->refresh();
	}
}
void makesame(int pos,int cnt,int d){
	if(cnt==root->size)root->makesame(d);
	else if(pos==1){
		splay(kth(cnt+1),null);
		root->ch[0]->makesame(d);
		root->refresh();
	}
	else if(pos+cnt-1==root->size){
		splay(kth(pos-1),null);
		root->ch[1]->makesame(d);
		root->refresh();
	}
	else{
		splay(kth(pos-1),null);
		splay(kth(pos+cnt),root);
		root->ch[1]->ch[0]->makesame(d);
		root->ch[1]->refresh();
		root->refresh();
	}
}
void reverse(int pos,int cnt){
	if(cnt==root->size)root->reverse();
	else if(pos==1){
		splay(kth(cnt+1),null);
		root->ch[0]->reverse();
		root->refresh();
	}
	else if(pos+cnt-1==root->size){
		splay(kth(pos-1),null);
		root->ch[1]->reverse();
		root->refresh();
	}
	else{
		splay(kth(pos-1),null);
		splay(kth(pos+cnt),root);
		root->ch[1]->ch[0]->reverse();
		root->ch[1]->refresh();
		root->refresh();
	}
}
int getsum(int pos,int cnt){
	if(!cnt)return 0;
	if(cnt==root->size)return root->sum;
	else if(pos==1){
		splay(kth(cnt+1),null);
		return root->ch[0]->sum;
	}
	else if(pos+cnt-1==root->size){
		splay(kth(pos-1),null);
		return root->ch[1]->sum;
	}
	else{
		splay(kth(pos-1),null);
		splay(kth(pos+cnt),root);
		return root->ch[1]->ch[0]->sum;
	}
}
int maxsum(){
	if(root==null)return 0;
	root->pushdown();
	return root->maxsum;
}
node *build(int l,int r){
	if(l>r)return null;
	int mid=(l+r)>>1;
	node *x=newnode(a[mid]);
	if((x->ch[0]=build(l,mid-1))!=null)x->ch[0]->p=x;
	if((x->ch[1]=build(mid+1,r))!=null)x->ch[1]->p=x;
	x->refresh();
	return x;
}
void removetree(node *x){
	if(x==null)return;
	removetree(x->ch[0]);
	removetree(x->ch[1]);
	delete x;
}
node *kth(int k){
	node *rt=root;
	int d;
	while(rt){
		rt->pushdown();
		if(k==rt->ch[0]->size+1)return rt;
		if((d=k>rt->ch[0]->size))k-=rt->ch[0]->size+1;
		rt=rt->ch[d];
	}
	return null;
}
void splay(node *x,node *tar){
	while(x->p!=tar){
		if(x->p->p==tar){
			rot(x->p,dir(x)^1);
			break;
		}
		if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
		else rot(x->p,dir(x)^1);
		rot(x->p,dir(x)^1);
	}
}
void rot(node *x,int d){
	node *y=x->ch[d^1];
	x->ch[d^1]=y->ch[d];
	if(y->ch[d]!=null)y->ch[d]->p=x;
	y->p=x->p;
	if(x->p!=null)x->p->ch[dir(x)]=y;
	else root=y;
	y->ch[d]=x;
	x->p=y;
	x->refresh();
	y->refresh();
}