洛谷P2042 [NOI2005]维护数列

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<stack>
#define Tp Treap*
#define DTp pair<Tp,Tp>
#define ft first
#define sc second
#define INF 0x7f7f7f7f
#define MAXN 500000+10
using namespace std;
int n,m;
int a[MAXN];
struct Treap{
    Tp l;Tp r;
    int key,fix;
    int size,sum,lx,rx,mx,tag;
};
Tp root;
stack<Tp> s;
Tp new_node(int v){
    Tp ret;
    if(s.empty())ret=new Treap;
    else ret=s.top(),s.pop();
    ret->l=ret->r=NULL;
    ret->key=ret->sum=v;
    ret->lx=ret->rx=ret->mx=v;
    ret->tag=-INF;
    ret->size=1,ret->fix=rand();
    return ret;
}
int Size(Tp A){return (A?A->size:0);}
int Sum(Tp A){return (A?A->sum:0);}
int Lx(Tp A){return (A?A->lx:-INF);}
int Rx(Tp A){return (A?A->rx:-INF);}
int Mx(Tp A){return (A?A->mx:-INF);}
void upd(Tp A){
    A->size=Size(A->l)+Size(A->r)+1;
    A->sum=Sum(A->l)+Sum(A->r)+A->key;
    A->mx=max(max(Mx(A->l),Mx(A->r)),A->key+max(Rx(A->l),0)+max(Lx(A->r),0));
    A->lx=max(Lx(A->l),Sum(A->l)+A->key+max(Lx(A->r),0));
    A->rx=max(Rx(A->r),Sum(A->r)+A->key+max(Rx(A->l),0));
}
void Print(Tp A){
    if(!A)return;
 //  pushdown(A); 
 //   printf("key=%d,size=%d,sum=%d,lx=%d,rx=%d,mx=%d\n",A->key,A->size,A->sum,A->lx,A->rx,A->mx);
    Print(A->l);
    printf("%d ",A->key);
    Print(A->r);
    if(A==root)printf("\n");    
}
void update(Tp A,int x){
    if(!A||-INF==x)return;
    if(x!=INF){
        A->tag=x;
        A->key=x;
        A->sum=x*A->size;
        A->mx=A->lx=A->rx=(x>0?A->sum:x);
    }
    else{
        if(A->tag!=INF&&A->tag!=-INF)return;
        swap(A->l,A->r);
        swap(A->lx,A->rx);
        A->tag=-A->tag;
    }
}
void pushdown(Tp A){
    update(A->l,A->tag);
    update(A->r,A->tag);
    A->tag=-INF;
}
Tp build(int L,int R){
    if(L>R)return NULL;
    int mid=(L+R)>>1;
    Tp ret=new_node(a[mid]);
    ret->l=build(L,mid-1);
    ret->r=build(mid+1,R);
    upd(ret);
    return ret;
}
Tp Merge(Tp A,Tp B){
    if(!A)return B;
    if(!B)return A;
    if(A->fix<B->fix){
        pushdown(A);
        A->r=Merge(A->r,B);
        upd(A);
        return A;
    }
    else{
        pushdown(B);
        B->l=Merge(A,B->l);
        upd(B);
        return B;
    }
}
DTp Split(Tp A,int k){
    if(!A)return DTp(NULL,NULL);
    pushdown(A);    
    DTp y;
    if(Size(A->l)>=k){
        y=Split(A->l,k);
        A->l=y.sc;
        upd(A);
        y.sc=A;
    }
    else{
        y=Split(A->r,k-Size(A->l)-1);
        A->r=y.ft;
        upd(A);
        y.ft=A;
    }
    return y;
}
int pos,len;
void Insert(){
    scanf("%d%d",&pos,&len);
    for(int i=1;i<=len;i++)scanf("%d",&a[i]);
    DTp x=Split(root,pos);
    root=Merge(x.ft,Merge(build(1,len),x.sc));
}
void Del(Tp A){
    if(!A)return;
    s.push(A);
    Del(A->l);
    Del(A->r);
}
void Delete(){
    scanf("%d%d",&pos,&len);
    DTp x=Split(root,pos-1);
    DTp y=Split(x.sc,len);
    Del(y.ft);
    root=Merge(x.ft,y.sc);
}
void MakeSame(){
    int v;
    scanf("%d%d%d",&pos,&len,&v);
    DTp x=Split(root,pos-1);
    DTp y=Split(x.sc,len);
    update(y.ft,v);
    root=Merge(x.ft,Merge(y.ft,y.sc));
}
void Rev(){
    scanf("%d%d",&pos,&len);
    DTp x=Split(root,pos-1);
    DTp y=Split(x.sc,len);
    update(y.ft,INF);
    root=Merge(x.ft,Merge(y.ft,y.sc));
}
int GetSum(){
    scanf("%d%d",&pos,&len);
    if(!len)return 0;
    DTp x=Split(root,pos-1);
    DTp y=Split(x.sc,len);
    int ans=y.ft->sum;
    root=Merge(x.ft,Merge(y.ft,y.sc));
    return ans;
}
int MaxSum(){
    return root->mx;
}
void init(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    root=build(1,n);
}
void solve(){
    char s[20];
    while(m--){
        scanf("%s",s);
        if('I'==s[0])Insert();
        else if('D'==s[0])Delete();
        else if('M'==s[0]&&'E'==s[3])MakeSame();
        else if('R'==s[0])Rev();
        else if('G'==s[0])printf("%d\n",GetSum());
        else printf("%d\n",MaxSum());
    }
}
int main()
{
//    freopen("testdata.in.txt","r",stdin);
//    freopen("my.out","w",stdout);
    init();
    solve();
    return 0;
}

 

posted @ 2017-12-26 00:34  white_hat_hacker  阅读(102)  评论(0编辑  收藏  举报