• P2042 [NOI2005]维护数列 平衡树


    最大序列和小白逛公园做过 

    区间修改的优先级高于区间翻转的优先级(之前有题01串翻转)

    序列维护平衡树 平衡树维护的是下标  因此中序遍历就是原序列

    每个结点维护的都是结点  不像线段树可以维护区间  所以build 的操作有一些不一样 

    这题还卡空间  所以要弄一个简单的回收操作

    注意up的顺序  必须从下到上  因为这个wa了好久

    非常好(难调)的平衡树题

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    queue<int>q;
    
    int lmax[N],rmax[N],siz[N],son[N][2],id[N],sum[N],maxans[N],fa[N],lson,rson,col[N],rev[N],root,v[N],ncnt,a[N],m,n;
    
    int chk(int x)
    {
        return son[fa[x]][1]==x;
    }
    
    void up(int pos)
    {
        lson=son[pos][0],rson=son[pos][1];
        sum[pos]=sum[lson]+sum[rson]+v[pos];
        siz[pos]=siz[lson]+siz[rson]+1;
        lmax[pos]=max(lmax[lson],sum[lson]+v[pos]+lmax[rson]);
        rmax[pos]=max(rmax[rson],sum[rson]+v[pos]+rmax[lson]);
        maxans[pos]=max(max(maxans[lson],maxans[rson]),v[pos]+rmax[lson]+lmax[rson]);
    }
    void down(int pos)
    {
        lson=son[pos][0];rson=son[pos][1];
        if(col[pos])
        {
            col[pos]=rev[pos]=0;//要删除区间翻转操作
            if(lson)col[lson]=1,v[lson]=v[pos],sum[lson]=v[pos]*siz[lson];
            if(rson)col[rson]=1,v[rson]=v[pos],sum[rson]=v[pos]*siz[rson];
            if(v[pos]>=0)
            {
                if(lson)maxans[lson]=rmax[lson]=lmax[lson]=sum[lson];
                if(rson)maxans[rson]=rmax[rson]=lmax[rson]=sum[rson];
            }
            else
            {
                if(lson)lmax[lson]=rmax[lson]=0,maxans[lson]=v[pos];
                if(rson)lmax[rson]=rmax[rson]=0,maxans[rson]=v[pos];
            }
        }
        if(rev[pos])
        {
            rev[pos]=0;
            rev[lson]^=1;rev[rson]^=1;
            swap(lmax[lson],rmax[lson]);
            swap(lmax[rson],rmax[rson]);
            swap(son[lson][0],son[lson][1]);
            swap(son[rson][0],son[rson][1]);
        }
    }
    
    void rotate(int x)
    {
        int y=fa[x],z=fa[y],k=chk(x),w=son[x][k^1];
        son[y][k]=w;fa[w]=y;
        son[z][chk(y)]=x;fa[x]=z;
        son[x][k^1]=y;fa[y]=x;
        up(y);up(x);//up必须自下往上的  我这里写成up(x),up(y)就一直wa
    }
    
    void splay(int x,int goal=0)
    {
        while(fa[x]!=goal)
        {
            int y=fa[x],z=fa[y];
            if(z!=goal)
            {
                if(chk(x)==chk(y))rotate(y);
                else rotate(x);
            }
            rotate(x);
        }
        if(!goal)root=x;
    }
    
    int find1(int x,int k)
    {
        down(x);
        if(siz[son[x][0]]+1==k)return x;
        if(siz[son[x][0]]>=k)return find1(son[x][0],k);
        else return find1(son[x][1],k-siz[son[x][0]]-1);
    }
    
    void recycle(int x)
    {
        if(son[x][0])recycle(son[x][0]);
        if(son[x][1])recycle(son[x][1]);
        q.push(x);
        son[x][0]=son[x][1]=col[x]=rev[x]=fa[x]=0;
    }
    
    int split(int k,int tot)
    {
        int x=find1(root,k),y=find1(root,k+tot+1);
        splay(x);splay(y,x);
        return son[son[root][1]][0];
    }
    
    int qsum(int k,int tot)
    {
        return sum[split(k,tot)];
    }
    
    void upsum(int k,int tot,int val)
    {
        int x=split(k,tot);
        int y=fa[x];
        col[x]=1;
        v[x]=val;sum[x]=siz[x]*val;
        if(v[x]>=0)maxans[x]=lmax[x]=rmax[x]=sum[x];
        else lmax[x]=rmax[x]=0,maxans[x]=val;
        up(y);up(fa[y]);
    }
    
    void rever(int k,int tot)
    {
        int x=split(k,tot),y=fa[x];
        if(!col[x])
        {
            rev[x]^=1;
            swap(son[x][0],son[x][1]);
            swap(lmax[x],rmax[x]);
            up(y);up(fa[y]);
        }
    }
    
    void del(int k,int tot)
    {
        int x=split(k,tot),y=fa[x];
        recycle(x);
        son[y][0]=0;
        up(y);up(fa[y]);
    }
    
    void build(int l,int r,int f)
    {
        int mid=(l+r)>>1,now=id[mid],pre=id[f];
        if(l==r)
        {
            maxans[now]=sum[now]=a[l];
            col[now]=rev[now]=0;
            lmax[now]=rmax[now]=max(0,a[l]);
            siz[now]=1;
        }
        if(l<mid)build(l,mid-1,mid);
        if(r>mid)build(mid+1,r,mid);
        v[now]=a[mid];fa[now]=pre;
        up(now);son[pre][mid>=f]=now;
    }
    
    void insert(int k,int tot)
    {
        rep(i,1,tot)scanf("%d",&a[i]);
        rep(i,1,tot)
        {
            if(!q.empty())id[i]=q.front(),q.pop();
            else id[i]=++ncnt;
        }
        build(1,tot,0);
        int z=id[(1+tot)>>1];
        int x=find1(root,k+1),y=find1(root,k+2);
        splay(x);splay(y,x);
    
        fa[z]=y;son[y][0]=z;
        up(y);up(x);
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        a[1]=a[n+2]=maxans[0]=-inf;
        rep(i,1,n)scanf("%d",&a[i+1]);
        rep(i,1,n+2)id[i]=i;
        build(1,n+2,0);
        root=(3+n)>>1;ncnt=n+2;
        int k,tot,val;
        char ch[10];
        int jjj=0;
        while(m--)
        {
            scanf("%s",ch);
            if(ch[0]!='M'||ch[2]!='X')scanf("%d%d",&k,&tot);
            if(ch[0]=='I')insert(k,tot);
            if(ch[0]=='D')del(k,tot);
            if(ch[0]=='M')
            {
                if(ch[2]=='X')printf("%d
    ",maxans[root]);
                else scanf("%d",&val),upsum(k,tot,val);
            }
            if(ch[0]=='R')rever(k,tot);
            if(ch[0]=='G')printf("%d
    ",qsum(k,tot));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/bxd123/p/11301602.html
Copyright © 2020-2023  润新知