zoukankan      html  css  js  c++  java
  • HYSBZ 1500 维修数列

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1500

    操作1:把要插入的数字先建成一颗树,然后splay相应位置,直接将树连上去

    操作2,3,4,5:都是splay普通操作

    操作6:像维护线段树一样,同时维护max,maxl,maxr就行了

    注意点:

    旋转时maxl和maxr也要交换

    要使用内存池,当弹出一个节点时,将它的两个子树丢进内存池中

    same的值可能为0,所以要设为inf

    max不能为空,所以初始应设成-inf,而不是0,否则update时会出错

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    const int N=5e5+5;
    const int inf=1e9;
    int head,tail,q[N*10],root;
    int a[N],b[N],f[N],ch[N][2],key[N],sz[N],same[N],rev[N],sum[N],maxl[N],maxr[N],maxx[N];
    inline void Clear(int x)
    {
        f[x]=ch[x][0]=ch[x][1]=key[x]=sz[x]=rev[x]=sum[x]=maxl[x]=maxr[x]=0;
        same[x]=inf;
        maxx[x]=-inf;
    }
    inline int get(int x)
    {
        return ch[f[x]][1]==x;
    }
    inline void delp(int x)
    {
        q[++tail]=x;
    }
    int newp()
    {
        head++;
        if (ch[q[head]][0]) delp(ch[q[head]][0]);
        if (ch[q[head]][1]) delp(ch[q[head]][1]);
        Clear(q[head]);
        return q[head];
    }
    void update(int x)
    {
        sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
        sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];
        maxl[x]=max(maxl[ch[x][0]],key[x]+sum[ch[x][0]]+maxl[ch[x][1]]);
        maxr[x]=max(maxr[ch[x][1]],key[x]+sum[ch[x][1]]+maxr[ch[x][0]]);
        maxx[x]=max(maxx[ch[x][0]],maxx[ch[x][1]]);
        maxx[x]=max(maxx[x],maxr[ch[x][0]]+key[x]+maxl[ch[x][1]]);
    }
    void pushdown(int x)
    {
        if (x==0) return;
        if (same[x]!=inf)
        {
            if (ch[x][0])
            {
                int lch=ch[x][0];
                key[lch]=same[x];
                sum[lch]=sz[lch]*same[x];
                if (same[x]>=0)
                    maxx[lch]=maxl[lch]=maxr[lch]=sum[lch];
                else
                {
                    maxx[lch]=same[x];
                    maxl[lch]=maxr[lch]=0;
                }
                same[lch]=same[x];
            }
            if (ch[x][1])
            {
                int rch=ch[x][1];
                key[rch]=same[x];
                sum[rch]=sz[rch]*same[x];
                if (same[x]>=0)
                    maxx[rch]=maxl[rch]=maxr[rch]=sum[rch];
                else
                {
                    maxx[rch]=same[x];
                    maxl[rch]=maxr[rch]=0;
                }
                same[rch]=same[x];
            }
            same[x]=inf;
        }
        if (rev[x])
        {
            if (ch[x][0])
            {
                int now=ch[x][0];
                rev[now]^=1;
                swap(ch[now][0],ch[now][1]);
                swap(maxl[now],maxr[now]);
            }
            if (ch[x][1])
            {
                int now=ch[x][1];
                rev[now]^=1;
                swap(ch[now][0],ch[now][1]);
                swap(maxl[now],maxr[now]);
            }
            rev[x]=0;
        }
    }
    int build(int l,int r,int fa,int *val)
    {
        if (l>r) return 0;
        int mid=(l+r)>>1;
        int now=newp();
        f[now]=fa;key[now]=val[mid];maxx[now]=val[mid];
        int lch=build(l,mid-1,now,val);
        int rch=build(mid+1,r,now,val);
        ch[now][0]=lch;ch[now][1]=rch;
        update(now);
        return now;
    }
    void Rotate(int x)
    {
        pushdown(f[x]);
        pushdown(x);
        int fa=f[x],ff=f[fa],kind=get(x);
        ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
        ch[x][kind^1]=fa;f[fa]=x;
        f[x]=ff;
        if (ff)
            ch[ff][ch[ff][1]==fa]=x;
        update(fa);
        update(x);
    }
    void splay(int x,int y)
    {
        for(int fa;(fa=f[x])!=y;Rotate(x))
            if (f[fa]!=y)
                Rotate((get(fa)==get(x))?fa:x);
        if (y==0) root=x;
    }
    int Find(int x)
    {
        int now=root;
        while(1)
        {
            pushdown(now);
            if (ch[now][0]&&sz[ch[now][0]]>=x)
                now=ch[now][0];
            else
            {
                x-=sz[ch[now][0]];
                if (x==1) return now;
                x--;
                now=ch[now][1];
            }
        }
    }
    
    void Treaval(int x) {
        if(x) {
            pushdown(x);
            Treaval(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d sum = %2d maxsum=%2d 
    ",x,ch[x][0],ch[x][1],f[x],sz[x],key[x],sum[x],maxx[x]);
            Treaval(ch[x][1]);
        }
    }
    void debug() {printf("%d
    ",root);Treaval(root);}
    
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        a[1]=-inf;a[n+2]=inf;maxx[0]=-inf;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i+1]);
        for(int i=1;i<=500000;i++)
            delp(i);
        root=build(1,n+2,0,a);
        char s[20];
        int pos,tot,c;
        while(m--)
        {
            scanf("%s",s);
            switch(s[0])
            {
                case 'I':
                {
                    scanf("%d%d",&pos,&tot);
                    for(int i=1;i<=tot;i++)
                        scanf("%d",&b[i]);
                    int now=build(1,tot,0,b);
                    int aa=Find(pos+1);
                    int bb=Find(pos+2);
                    splay(aa,0);
                    splay(bb,aa);
                    ch[ch[root][1]][0]=now;
                    f[now]=ch[root][1];
                    update(ch[root][1]);
                    update(root);
                    //debug();
                    break;
                }
                case 'D':
                {
                    scanf("%d%d",&pos,&tot);
                    int aa=Find(pos);
                    int bb=Find(pos+tot+1);
                    splay(aa,0);
                    splay(bb,aa);
                    delp(ch[ch[root][1]][0]);
                    ch[ch[root][1]][0]=0;
                    update(ch[root][1]);
                    update(root);
                    //debug();
                    break;
                }
                case 'M':
                    if (s[2]=='K')
                    {
                        scanf("%d%d%d",&pos,&tot,&c);
                        int aa=Find(pos);
                        int bb=Find(pos+tot+1);
                        splay(aa,0);
                        splay(bb,aa);
                        int now=ch[ch[root][1]][0];
                        same[now]=c;
                        key[now]=c;
                        sum[now]=c*sz[now];
                        if (c>=0)
                            maxx[now]=maxl[now]=maxr[now]=sum[now];
                        else
                        {
                            maxx[now]=c;
                            maxl[now]=maxr[now]=0;
                        }
                        update(ch[root][1]);
                        update(root);
                        //debug();
                    }
                    else
                    {
                        int aa=Find(1);
                        int bb=Find(sz[root]);
                        splay(aa,0);
                        splay(bb,aa);
                        printf("%d
    ",maxx[ch[ch[root][1]][0]]);
                    }
                    break;
                case 'R':
                {
                    scanf("%d%d",&pos,&tot);
                    if (tot==1) break;
                    int aa=Find(pos);
                    int bb=Find(pos+tot+1);
                    splay(aa,0);
                    splay(bb,aa);
                    int now=ch[ch[root][1]][0];
                    rev[now]^=1;
                    swap(ch[now][0],ch[now][1]);
                    swap(maxl[now],maxr[now]);
                    break;
                }
                case 'G':
                {
                    scanf("%d%d",&pos,&tot);
                    int aa=Find(pos);
                    int bb=Find(pos+tot+1);
                    splay(aa,0);
                    splay(bb,aa);
                    //debug();
                    printf("%d
    ",sum[ch[ch[root][1]][0]]);
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    第三次作业
    读大道至简第三章有感
    AlphaMobileControls介绍
    wince下GetManifestResourceStream得到的Stream是null的解决
    Wince下实现ImageButton
    windows phone 8的新特性
    没有开发者账号,如何解锁wp8设备
    windows phone8手机玩玩
    windows phone7开发环境配置错误
    如何解决office2007每次打开都要正在配置
  • 原文地址:https://www.cnblogs.com/bk-201/p/7410346.html
Copyright © 2011-2022 走看看