bzoj1500

#include<cstdio>
#include<algorithm>
#include<iostream>
#define inf 2000000000
#define N 1100000
using namespace std;
int p,t,k,n,m,root,a[N],size[N],key[N],ta,l,r,fa[N],cov[N],q[N],tot,ma[N],la[N],ra[N],rev[N],c[N][2],sum[N];
 
inline int pick()  
{
    if(ta)return q[ta--];
    return ++tot;
}
  
inline void update(int x)
{
    if(!x)return;
    la[x]=max(la[c[x][0]],sum[c[x][0]]+key[x]+max(0,la[c[x][1]]));
    ra[x]=max(ra[c[x][1]],sum[c[x][1]]+key[x]+max(0,ra[c[x][0]]));
    ma[x]=max(max(ma[c[x][0]],ma[c[x][1]]),key[x]+max(0,ra[c[x][0]])+max(0,la[c[x][1]]));
    sum[x]=sum[c[x][0]]+sum[c[x][1]]+key[x];
    size[x]=size[c[x][0]]+size[c[x][1]]+1;
}
  
int build(int l,int r) 
{
    int mid=(l+r)>>1;
    int L=0,R=0;
    if (l<mid)L=build(l,mid-1);
    int t=pick();
    if (r>mid)R=build(mid+1,r);
    key[t]=a[mid];
    cov[t]=-inf;
    rev[t]=0;
    la[t]=ra[t]=ma[t]=-inf;
    if(L)fa[L]=t,c[t][0]=L;
    if(R)fa[R]=t,c[t][1]=R;
    update(t);
    return t;
}
  
inline void rotate(int x)
{
    int y=fa[x],z=fa[y],b;
    if (x==c[y][1])b=c[x][0]; else b=c[x][1];
    fa[x]=z; fa[y]=x;
    if(b)fa[b]=y;
    if(z)
    {
        if(c[z][0]==y)c[z][0]=x;
        else c[z][1]=x;
    }
    if(x==c[y][0])
    {
        c[x][1]=y;
        c[y][0]=b;
    }
    else
    {
        c[x][0]=y;
        c[y][1]=b;
    }
    update(y);
}
 
inline void revv(int x)
{
    if(!x)return;
    swap(c[x][0],c[x][1]);
    swap(la[x],ra[x]);
    rev[x]^=1;
}
 
inline void recc(int x,int k)
{
    if(!x)return;
    key[x]=cov[x]=k;
    sum[x]=size[x]*k;
    la[x]=ma[x]=ra[x]=max(k,k*size[x]);
}
 
inline void down(int x)
{
    if(!x)return;
    if(rev[x])
    {
        revv(c[x][0]);
        revv(c[x][1]);
        rev[x]=0;
    }
    if(cov[x]!=-inf)
    {
        recc(c[x][0],cov[x]);
        recc(c[x][1],cov[x]);
        cov[x]=-inf;
    }
}
 
void relax(int x,int rt)
{
    if (x!=rt)relax(fa[x],rt);
    down(x);
}
 
int which(int x)
{
    return c[fa[x]][1]==x;
}
  
void splay(int x,int rt)
{
    relax(x,rt);
    while(fa[x]!=rt)
    {
        if(fa[fa[x]]!=rt)
        {
            if (which(x)==which(fa[x]))rotate(fa[x]);
            else rotate(x);
        }
        rotate(x);
    }
    update(x);
    if (!rt)root=x;
}
 
int find(int rt,int k)
{
    down(rt);
    if(k==size[c[rt][0]]+1)return rt;
    if(k<size[c[rt][0]]+1)return find(c[rt][0],k);
    return find(c[rt][1],k-size[c[rt][0]]-1);
}
 
void del(int &x)
{
    if(!x)return;
    q[++ta]=x;
    fa[x]=0;
    del(c[x][0]);
    del(c[x][1]);
    x=0;
}
 
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=2;i<=n+1; i++)scanf("%d",a+i);
    la[0]=ra[0]=ma[0]=-inf;
    root=build(1,n+2);
    char s[20];
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s);
        if(s[0]=='I')
        {
            scanf("%d%d",&p,&t);
            l=find(root,p+1);
            r=find(root,p+2);
            splay(r,0);
            splay(l,r);
            for(int j=1; j<=t;j++)scanf("%d",a+j);
            int tmp=build(1,t);
            fa[tmp]=l;
            c[l][1]=tmp;
            update(l);
            update(r);
        }
        if(s[0]=='D')
        {
            scanf("%d%d",&p,&t);
            l=find(root,p);
            r=find(root,p+t+1);
            splay(r,0);
            splay(l,r);
            del(c[l][1]);
            update(l);
            update(r);
        }
        if(s[0]=='M'&&s[2]=='K')
        {
            scanf("%d%d%d",&p,&t,&k);
            l=find(root,p);
            r=find(root,p+t+1);
            splay(r,0);
            splay(l,r);
            recc(c[l][1],k);
        }
        if(s[0]=='R')
        {
            scanf("%d%d",&p,&t);
            l=find(root,p);
            r=find(root,p+t+1);
            splay(r,0);
            splay(l,r);
            revv(c[l][1]);
        }
        if(s[0]=='G')
        {
            scanf("%d%d",&p,&t);
            l=find(root,p);
            r=find(root,p+t+1);
            splay(r,0);
            splay(l,r);
            printf("%d\n",sum[c[l][1]]);
        }
        if(s[2]=='X')
        {
            splay(n+2,0);
            splay(1,n+2);
            printf("%d\n",ma[c[1][1]]);
        } 
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值