zoukankan      html  css  js  c++  java
  • BZOJ 1500 [NOI2005]维修数列 FHQ Treap

    终于A了这题。。。这题还是很好。。。但是我太菜。。。重构了三遍qwq


    FHQ Treap大法好!qwq。。。~~

    Ins:直接拿输入造一棵树,把原来的树split成[1,pos],[pos+1,n],然后merge三棵树;

    Del:把要删的区间split出来,merge他两边的树,记着要回收内存;

    Mk-Same:把要改的区间split出来,打上标记,更新这棵树根的信息(见cover(x,v)),再merge回去;

    Rev:把要翻转的区间split出来,打上标记,更新这棵树根的信息(见reverse(x)),再merge回去;

    Get:把要求的区间split出来,输出sum[根],然后再merge回去;

    Mx:输出mx[根]

    维护最大子段和的思路跟线段树是类似的(链接

    顺便说一下自己当初犯的错误:

    1.没有及时下放rev标记;重构x1

    2.由于读取字符串用的getchar(),但是操作中有些串有负号。。。导致我读进来一堆负数。。。以后乖乖用字符串吧。。;重构x2,第三次重构才发现

    3.stk内存池开小了。。。以为自己哪里递归写错了MLE+RE,后来看到网上有用queue的,就水了一波结果水过了。。后来又换成了数组stk。。;重构x3

    代码:

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstdlib>
    #define R register int
    #define ls(x) (ch[x][0])
    #define rs(x) (ch[x][1])
    using namespace std;
    const int N=500010,Inf=10000010;
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } 
    int n,m,tot,rt,top,sz[N],ch[N][2],vl[N],mxl[N],mxr[N],mx[N],sum[N],tg[N],cov[N],dat[N],a[N>>1],stk[N<<1];
    inline int max(int a,int b) {return a>b?a:b;}
    inline int cre(int v) {R x; if(top) x=stk[top],--top; else x=++tot;
        sz[x]=1,ls(x)=rs(x)=tg[x]=0; cov[x]=Inf,dat[x]=rand();
        vl[x]=sum[x]=mx[x]=mxl[x]=mxr[x]=v; return x;
    }
    inline void upd(int x) {
        if(!x) return ; sz[x]=sz[ls(x)]+sz[rs(x)]+1; sum[x]=sum[ls(x)]+sum[rs(x)]+vl[x];
        mx[x]=max(max(mxl[rs(x)],0)+vl[x]+max(mxr[ls(x)],0),max(mx[ls(x)],mx[rs(x)]));
        mxl[x]=max(mxl[ls(x)],sum[ls(x)]+vl[x]+max(mxl[rs(x)],0));
        mxr[x]=max(mxr[rs(x)],sum[rs(x)]+vl[x]+max(mxr[ls(x)],0));
    }
    inline void cover(int x,int v) {vl[x]=cov[x]=v,sum[x]=sz[x]*v,mxl[x]=mxr[x]=max(sum[x],0),mx[x]=max(vl[x],sum[x]);}
    inline void reverse(int x) {swap(ls(x),rs(x)),swap(mxl[x],mxr[x]),tg[x]^=1;}
    inline void spread(int x) {
        if(tg[x]) {if(ls(x)) reverse(ls(x)); if(rs(x)) reverse(rs(x));} 
        if(cov[x]!=Inf) {if(ls(x)) cover(ls(x),cov[x]); if(rs(x)) cover(rs(x),cov[x]);} tg[x]=0,cov[x]=Inf;
    }
    inline int build(int l,int r) {
        if(l>r) return 0; R md=l+r>>1,v=a[md]; R x=cre(v);
        ls(x)=build(l,md-1),rs(x)=build(md+1,r); upd(x); return x;
    }
    inline void split(int o,int rk,int& x,int& y) {
        if(!o) {x=y=0; return ;} spread(o);
        if(rk>sz[ls(o)]) x=o,split(rs(x),rk-sz[ls(x)]-1,rs(x),y);
        else y=o,split(ls(y),rk,x,ls(y)); upd(o);
    }
    inline int merge(int x,int y) {
        if(!x||!y) return x|y; spread(x),spread(y);
        if(dat[x]<dat[y]) {rs(x)=merge(rs(x),y); upd(x); return x;}
        else {ls(y)=merge(x,ls(y)); upd(y); return y;}
    }
    inline void del(int x) {if(!x) return; del(ls(x)),stk[++top]=x,del(rs(x));}
    signed main() { R w,x,y,z; srand(100023323); vl[0]=mx[0]=-Inf,sum[0]=sz[0]=tg[0]=cov[0]=0;
        n=g(),m=g(); for(R i=1,x;i<=n;++i) a[i]=g(); rt=build(1,n); while(m--) { register char ch;
            while(!isalpha(ch=getchar())); if(ch=='M') {
                getchar(),ch=getchar(); if(ch=='K') {
                    while(!isspace(ch=getchar())); R pos=g(),tot=g(),c=g(); split(rt,pos-1,x,y),split(y,tot,y,z);
                    cover(y,c); rt=merge(x,merge(y,z));
                } else if(ch=='X') {printf("%d
    ",mx[rt]); while(!isspace(ch=getchar()));}
            } else if(ch=='I') {R pos=g(),tot=g(); for(R i=1,x;i<=tot;++i) a[i]=g(); z=build(1,tot);split(rt,pos,x,y),rt=merge(merge(x,z),y);} 
            else if(ch=='D') {while(!isspace(ch=getchar())); R pos=g(),tot=g(); split(rt,pos-1,x,y),split(y,tot,y,z),rt=merge(x,z); del(y);}
            else if(ch=='R') {while(!isspace(ch=getchar())); R pos=g(),tot=g(); split(rt,pos-1,x,y),split(y,tot,y,z); reverse(y); rt=merge(x,merge(y,z));}
            else if(ch=='G') {while(!isspace(ch=getchar())); R pos=g(),tot=g(); split(rt,pos-1,x,y),split(y,tot,y,z); printf("%d
    ",sum[y]); rt=merge(x,merge(y,z));}
        } 
    }

    2019.05.11

  • 相关阅读:
    将所有程序设置XML集中到一个单独XML配置文件的方法:使用appSettings元素的configSource元素
    MVC中JQuery文件引入的路径问题,@Url.Content函数
    EF的表连接方法Include()
    在使用EFCodeFirst中出现类型“System.Data.Objects.ObjectContext”在未被引用的程序集中定义的解决方案
    总结下遇到的C#新语法
    MVC3下的layout页面
    C#委托初探
    WebBrowser Control
    Python之面向对象二
    Python之面向对象一
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10849362.html
Copyright © 2011-2022 走看看