Splay(区间操作)伪模板 [BZOJ][1500][NOI2005]维修数列

#include<bits/stdc++.h>
#include<bits/stdtr1c++.h>
using namespace std;

const int MAXN=1e6+2333;
int n,m;
int a[MAXN];

namespace Splay {
    #define OTZ (ch[ch[root][1]][0])
    int root,cnt1;
    int st[MAXN],cnt2;
    int ch[MAXN][2],fa[MAXN],siz[MAXN];
    int key[MAXN],sum[MAXN];
    int lx[MAXN],rx[MAXN],mx[MAXN];
    int rev[MAXN],same[MAXN];
    void New_Node(int &x,int p,int val) {
        if (cnt2) x=st[cnt2--];
        else x=++cnt1;
        fa[x]=p,ch[x][0]=ch[x][1]=0,siz[x]=1;
        key[x]=sum[x]=lx[x]=rx[x]=mx[x]=val;
        rev[x]=same[x]=0;
    }
    void update_rev(int x) {
        if (!x) return;
        swap(ch[x][0],ch[x][1]);
        swap(lx[x],rx[x]);
        rev[x]^=1;
    }
    void update_same(int x,int val) {
        if (!x) return;
        key[x]=val;
        sum[x]=val*siz[x];
        lx[x]=rx[x]=mx[x]=max(key[x],sum[x]);
        same[x]=1;
    }
    void push_up(int x) {
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
        sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];
        lx[x]=max(lx[ch[x][0]],sum[ch[x][0]]+key[x]+max(0,lx[ch[x][1]]));
        rx[x]=max(rx[ch[x][1]],sum[ch[x][1]]+key[x]+max(0,rx[ch[x][0]]));
        mx[x]=max(0,rx[ch[x][0]])+key[x]+max(0,lx[ch[x][1]]);
        mx[x]=max(mx[x],max(mx[ch[x][0]],mx[ch[x][1]]));
    }
    void push_down(int x) {
        if (!x) return;
        if (rev[x]) update_rev(ch[x][0]),update_rev(ch[x][1]),rev[x]=0;
        if (same[x]) update_same(ch[x][0],key[x]),update_same(ch[x][1],key[x]),same[x]=0;
    }
    void build_tree(int &x,int l,int r,int p) {
        if (l>r) return;
        int mid=l+r>>1;
        New_Node(x,p,a[mid]);
        build_tree(ch[x][0],l,mid-1,x);
        build_tree(ch[x][1],mid+1,r,x);
        push_up(x);
    }
    void rotate(int x,int &k) {
        int y=fa[x],z=fa[y],d=(ch[y][1]==x);
        if (y!=k) ch[z][ch[z][1]==y]=x;
        else k=x; fa[x]=z;
        ch[y][d]=ch[x][d^1],fa[ch[x][d^1]]=y;
        ch[x][d^1]=y,fa[y]=x;
        push_up(y),push_up(x);
    }
    void MIDD(int x,int &k) {
        if (fa[x]!=k) push_down(fa[fa[x]]);
        push_down(fa[x]),push_down(x);
        rotate(x,k);
    }
    void splay(int x,int &k) {
        for (int y; (y=fa[x])&&x!=k; MIDD(x,k))
            if (y!=k)
                MIDD((ch[y][0]==x)^(ch[fa[y]][0]==y) ? x:y,k);
    }
    int kth(int x,int k) {
        push_down(x);
        if (siz[ch[x][0]]+1==k) return x;
        else if (siz[ch[x][0]]>=k) return kth(ch[x][0],k);
        else return kth(ch[x][1],k-siz[ch[x][0]]-1);
    }
    void Insert(int pl,int num) {
        for (int i=1; i<=num; i++) scanf("%d",&a[i]);
        splay(kth(root,pl+1),root);
        splay(kth(root,pl+2),ch[root][1]);
        build_tree(OTZ,1,num,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
    }
    void Recycle_Node(int x) {
        if (!x) return;
        st[++cnt2]=x;
        Recycle_Node(ch[x][0]);
        Recycle_Node(ch[x][1]);
    }
    void Delt(int pl,int num) {
        splay(kth(root,pl),root);
        splay(kth(root,pl+num+1),ch[root][1]);
        Recycle_Node(OTZ);
        fa[OTZ]=0;
        OTZ=0;
        push_up(ch[root][1]);
        push_up(root);
    }
    void Make_Same(int pl,int num,int val) {
        splay(kth(root,pl),root);
        splay(kth(root,pl+num+1),ch[root][1]);
        update_same(OTZ,val);
        push_up(ch[root][1]);
        push_up(root);
    }
    void Reverse(int pl,int num) {
        splay(kth(root,pl),root);
        splay(kth(root,pl+num+1),ch[root][1]);
        update_rev(OTZ);
        push_up(ch[root][1]);
        push_up(root);
    }
    int Get_Sum(int pl,int num) {
        splay(kth(root,pl),root);
        splay(kth(root,pl+num+1),ch[root][1]);
        return sum[OTZ];
    }
    int Get_Max(int pl,int num) {
        splay(kth(root,pl),root);
        splay(kth(root,pl+num+1),ch[root][1]);
        return mx[OTZ];
    }
    void Initialization() {
        New_Node(root,0,-233);
        New_Node(ch[root][1],root,-233);
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        build_tree(OTZ,1,n,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
        mx[0]=-0x3f3f3f3f;
    }
    #undef OTZ
} using namespace Splay;

int main() {
    scanf("%d%d",&n,&m);
    Initialization();
    char opt[233];
    int x,y,z;
    while (m--) {
        scanf("%s",opt);
        if (strcmp(opt,"INSERT")==0)
            scanf("%d%d",&x,&y),Insert(x,y);
        else if (strcmp(opt,"DELETE")==0)
            scanf("%d%d",&x,&y),Delt(x,y);
        else if (strcmp(opt,"MAKE-SAME")==0)
            scanf("%d%d%d",&x,&y,&z),Make_Same(x,y,z);
        else if (strcmp(opt,"REVERSE")==0)
            scanf("%d%d",&x,&y),Reverse(x,y);
        else if  (strcmp(opt,"GET-SUM")==0)
            scanf("%d%d",&x,&y),printf("%d\n",Get_Sum(x,y));
        else if (strcmp(opt,"MAX-SUM")==0)
            printf("%d\n",Get_Max(1,siz[root]-2));
    }
    return 0;
}

 

posted @ 2018-08-24 12:32  QingCai_DCF  阅读(129)  评论(0编辑  收藏  举报