bzoj 1500 [NOI2005]维修数列 (splay)

4 篇文章 0 订阅

题目大意:略

调了好久终于过了!

我犯了一个错误,虽然我记得在翻转pushdown的时候交换lx和rx

但我应该翻转的是左儿子和右儿子的lx和rx!而不是当前节点的lx和rx

因为pushup的时候是根据左右儿子的lx和rx更新的!

还有就是在find的时候下传标记,在转到根的时候pushup

很丧病的题

然后我的代码在洛谷上过了,可bzoj上迷之CE了,害得我的提交记录里多了13%的CE

#include <cstdio>
#include <algorithm>
#include <cstring>
#define root d[0].ch[1]
#define il inline
#define nu 7777
#define inf 500000
#define N 601000
using namespace std;

int n,m,hd,tl,tot;
char qq[20];
int ww[N],que[N*10];
struct SPLAY{
    int fa,ch[2],sz,val,sum,lx,rx,tx,tag,rev;
}d[N];
il int idf(int x){return d[d[x].fa].ch[0]==x?0:1;}
il void con(int x,int ff,int p){d[x].fa=ff,d[ff].ch[p]=x;}
il int cre(int val)
{
    int x=(hd>=tl)?que[tl++]:++tot;
    d[x].lx=d[x].rx=d[x].tx=d[x].val=d[x].sum=val;
    d[x].tag=nu,d[x].sz=1;return x;
}
il void des(int x)
{
    memset(&d[x],0,sizeof(d[x]));
    que[++hd]=x;
}
il void pushup(int x)
{
    #define ls d[x].ch[0]
    #define rs d[x].ch[1]
    d[x].sz=d[ls].sz+d[rs].sz+1;
    d[x].sum=d[ls].sum+d[rs].sum+d[x].val;
    if(ls&&rs)
    {
        d[x].lx=max(d[ls].lx,d[ls].sum+max(0,d[x].val+max(0,d[rs].lx)));
        d[x].rx=max(d[rs].rx,d[rs].sum+max(0,d[x].val+max(0,d[ls].rx)));
        d[x].tx=max(d[ls].tx,d[rs].tx);
        d[x].tx=max(d[x].tx,max(0,d[ls].rx)+d[x].val+max(0,d[rs].lx));
        d[x].tx=max(d[x].tx,max(d[x].lx,d[x].rx));
    }
    if(ls&&!rs)
    {
        d[x].lx=max(d[ls].lx,d[ls].sum+d[x].val);
        d[x].rx=max(d[ls].rx,0)+d[x].val;
        d[x].tx=max(d[ls].tx,max(d[x].lx,d[x].rx));
    }
    if(!ls&&rs)
    {
        d[x].lx=d[x].val+max(d[rs].lx,0);
        d[x].rx=max(d[rs].rx,d[rs].sum+d[x].val);
        d[x].tx=max(d[rs].tx,max(d[x].lx,d[x].rx));
    }
    if(!ls&&!rs)
    {
        d[x].lx=d[x].rx=d[x].tx=d[x].val;
    }
    #undef ls
    #undef rs
}
il void pushdown(int x)
{
    #define ls d[x].ch[0]
    #define rs d[x].ch[1]
    if(d[x].tag!=nu)
    {
        d[ls].tag=d[rs].tag=d[ls].val=d[rs].val=d[x].tag;
        d[ls].lx=d[ls].rx=d[ls].tx=max(d[x].tag,d[x].tag*d[ls].sz);
        d[rs].lx=d[rs].rx=d[rs].tx=max(d[x].tag,d[x].tag*d[rs].sz);
        d[ls].sum=d[ls].val*d[ls].sz;
        d[rs].sum=d[rs].val*d[rs].sz;
        d[x].tag=nu,d[x].rev=0;
    }
    if(d[x].rev)
    {
        swap(d[x].ch[0],d[x].ch[1]);
        d[ls].rev^=1,d[rs].rev^=1,d[x].rev=0;
        swap(d[ls].lx,d[ls].rx);
        swap(d[rs].lx,d[rs].rx);
    }
    #undef ls
    #undef rs
}
il void rot(int x)
{
    int y=d[x].fa;int ff=d[y].fa;int px=idf(x);int py=idf(y);
    con(d[x].ch[px^1],y,px),con(y,x,px^1),con(x,ff,py);
    pushup(y),pushup(x);
}
il void splay(int x,int to)
{
    to=d[to].fa;
    while(d[x].fa!=to){
        int y=d[x].fa;
        if(d[y].fa==to) rot(x);
        else if(idf(y)==idf(x)) rot(y),rot(x);
        else rot(x),rot(x);
    }
}
int find_pos(int p)
{
    int x=root;
    while(1)
    {
        pushdown(x);
        if(d[d[x].ch[0]].sz>=p){
            x=d[x].ch[0];
            continue;
        }p-=d[d[x].ch[0]].sz;
        if(p==1) return x;
        p--,x=d[x].ch[1];
    }
}
int build(int l,int r,int ff)
{
    if(l>r) return 0;
    int mid=(l+r)>>1;
    int x=cre(ww[mid]);
    d[x].fa=ff;
    d[x].ch[0]=build(l,mid-1,x);
    d[x].ch[1]=build(mid+1,r,x);
    pushup(x);
    return x;
}
int gc()
{
    int rett=0,fh=1;char p=getchar();
    while(p<'0'||p>'9') {if(p=='-')fh=-1;p=getchar();}
    while(p>='0'&&p<='9'){rett=(rett<<3)+(rett<<1)+p-'0';p=getchar();}
    return rett*fh;
}
void Ins(int pos,int num)
{
    for(int i=1;i<=num;i++) ww[i]=gc();
    int x=find_pos(pos+1);splay(x,root);
    int y=find_pos(pos+2);splay(y,d[root].ch[1]);
    int rt=build(1,num,y);con(rt,y,0);
    pushup(y),pushup(x);
}
void clr(int x)
{
    if(d[x].ch[0]) clr(d[x].ch[0]);
    if(d[x].ch[1]) clr(d[x].ch[1]);
    des(x);
}
void Del(int pos,int num)
{
    int x=find_pos(pos);splay(x,root);
    int y=find_pos(pos+num+1);splay(y,d[x].ch[1]);
    clr(d[y].ch[0]);d[y].ch[0]=0;
    pushup(y),pushup(x);
}
void Same(int pos,int num,int val)
{
    int x=find_pos(pos);splay(x,root);
    int y=find_pos(pos+num+1);splay(y,d[x].ch[1]);
    int rt=d[y].ch[0];
    d[rt].val=d[rt].tag=val;
    d[rt].sum=val*d[rt].sz;
    d[rt].tx=d[rt].lx=d[rt].rx=max(d[rt].val,d[rt].sum);
    pushup(y),pushup(x);
}
void Rev(int pos,int num)
{
    int x=find_pos(pos);splay(x,root);
    int y=find_pos(pos+num+1);splay(y,d[x].ch[1]);
    int rt=d[y].ch[0];
    d[rt].rev^=1;
    swap(d[rt].lx,d[rt].rx);
}
int Getsum(int pos,int num)
{
    int x=find_pos(pos);splay(x,root);
    int y=find_pos(pos+num+1);splay(y,d[x].ch[1]);
    int rt=d[y].ch[0];
    return d[rt].sum;
}
/*
void pro_dfs(int x)
{
    pushdown(x);
    //printf("%d %d %d %d\n",x,d[x].ch[0],d[x].ch[1],d[x].val);
    if(d[x].ch[0]) pro_dfs(d[x].ch[0]);
    if(d[x].ch[1]) pro_dfs(d[x].ch[1]);
    pushup(x);
}
void mid_dfs(int x)
{
    pushdown(x);
    if(d[x].ch[0]) mid_dfs(d[x].ch[0]);
    printf("%d ",d[x].val);
    if(d[x].ch[1]) mid_dfs(d[x].ch[1]);
}*/
int Maxsum()
{
    int x=find_pos(1);splay(x,root);
    int y=find_pos(n+2);splay(y,d[root].ch[1]);
    //pro_dfs(root);
    int rt=d[y].ch[0];
    return d[rt].tx;
}


int main()
{
    n=gc(),m=gc();
    for(int i=1;i<=n;i++) ww[i]=gc();
    ww[0]=ww[n+1]=-inf,hd=0,tl=1;
    root=build(0,n+1,0);
    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        scanf("%s",qq);
        if(qq[2]=='S'){
            x=gc(),y=gc();
            Ins(x,y);n+=y;
        }else if(qq[2]=='L'){
            x=gc(),y=gc();
            Del(x,y);n-=y;
        }else if(qq[2]=='K'){
            x=gc(),y=gc(),z=gc();
            Same(x,y,z);
        }else if(qq[2]=='V'){
            x=gc(),y=gc();
            Rev(x,y);
        }else if(qq[2]=='T'){
            x=gc(),y=gc();
            printf("%d\n",Getsum(x,y));
        }else{
            printf("%d\n",Maxsum());
        }
    }
    return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值