序列终结者

fhq treap+lazy标记

就是几个题拼起来而已

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"ctime"
using namespace std;

const int MAXN=5e4+5;
const int INF=0x3f3f3f3f;

int n,m,root,cnt;
int siz[MAXN],val[MAXN],mx[MAXN],rev[MAXN],sn[2][MAXN],pls[MAXN];
bool tag[MAXN];

int cret()
{
    siz[++cnt]=1;
    rev[cnt]=rand();
    return cnt;
}

void pushdown(int v)
{
    if(!tag[v]&&!pls[v]||!v) return;
    if(tag[v]){
        swap(sn[0][v],sn[1][v]);
        tag[sn[0][v]]^=1;
        tag[sn[1][v]]^=1;
        tag[v]=0;
    }if(pls[v]){
        mx[sn[0][v]]+=pls[v];
        mx[sn[1][v]]+=pls[v];
        val[sn[0][v]]+=pls[v];
        val[sn[1][v]]+=pls[v];
        pls[sn[0][v]]+=pls[v];
        pls[sn[1][v]]+=pls[v];
        pls[v]=0;
    }return;
}

void pushup(int v)
{
    siz[v]=siz[sn[0][v]]+siz[sn[1][v]]+1;
    mx[0]=val[0]=-INF;
    mx[v]=max(max(mx[sn[0][v]],mx[sn[1][v]]),val[v]);
    return;
}

int un(int x,int y)
{
    if(!x||!y) return x|y;
    if(rev[x]<rev[y]){
        pushdown(x);
        sn[1][x]=un(sn[1][x],y);
        pushup(x);
        return x;
    }pushdown(y);
    sn[0][y]=un(x,sn[0][y]);
    pushup(y);
    return y;
}

void dro(int k,int v,int &x,int &y)
{
    if(!k){x=y=0;return;}
    pushdown(k);
    if(siz[sn[0][k]]<v) x=k,dro(sn[1][k],v-siz[sn[0][k]]-1,sn[1][k],y);
    else y=k,dro(sn[0][k],v,x,sn[0][k]);
    pushup(k);
    return;
}

void cadd(int l,int r,int v)
{
    int x,y,z;
    dro(root,l-1,x,y);
    dro(y,r-l+1,y,z);
    val[y]+=v;mx[y]+=v;pls[y]+=v;
    root=un(x,un(y,z));
    return;
}

void cdro(int l,int r)
{
    int x,y,z;
    dro(root,l-1,x,y);
    dro(y,r-l+1,y,z);
    tag[y]^=1;
    root=un(x,un(y,z));
    return;
}

int cask(int l,int r)
{
    int x,y,z,ans;
    dro(root,l-1,x,y);
    dro(y,r-l+1,y,z);
    pushdown(y);pushup(y);
    ans=max(mx[y],val[y]);
    root=un(x,un(y,z));
    return ans;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i) root=un(root,cret());
    while(m--){
        int p,l,r,v;
        scanf("%d%d%d",&p,&l,&r);
        if(p==1){int v;scanf("%d",&v);cadd(l,r,v);}
        else if(p==2) cdro(l,r);
        else printf("%d\n",cask(l,r));
    }return 0;
}

猜你喜欢

转载自www.cnblogs.com/AH2002/p/10109485.html