记录编号 |
360820 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOI 2005]维护数列 |
最终得分 |
100 |
用户昵称 |
AntiLeaf |
是否通过 |
通过 |
代码语言 |
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();
}