• bzoj3272 Zgg吃东西


    题目描述:

    bz

    题解:

    线段树模拟费用流。

    想法和种树有点类似。

    每次取区间内权值和最大的一段,然后整体乘$-1$,代表再次选中时会去掉之前的影响。

    线段树维护一堆东西……

    小白逛公园双倍快乐。乘$-1$时交换正反。

    [滑稽]

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 100050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,m;
    int chg[50][2];
    struct n_8
    {
        int w,wl,wr,wu,pl,pr,pll,prr;
        n_8(){}
        n_8(int w,int wl,int wr,int wu,int pl,int pr,int pll,int prr):w(w),wl(wl),wr(wr),wu(wu),pl(pl),pr(pr),pll(pll),prr(prr){}
    };
    void chkmax(int&a,int&b,int c,int d,int e,int f)
    {
        if(c>e)a=c,b=d;
        else a=e,b=f;
    }
    void chkmax(int&a,int&b,int&c,int d,int e,int f,int g,int h,int i)
    {
        if(d>g)a=d,b=e,c=f;
        else a=g,b=h,c=i;
    }
    void chkmin(int&a,int&b,int c,int d,int e,int f)
    {
        if(c<e)a=c,b=d;
        else a=e,b=f;
    }
    void chkmin(int&a,int&b,int&c,int d,int e,int f,int g,int h,int i)
    {
        if(d<g)a=d,b=e,c=f;
        else a=g,b=h,c=i;
    }
    void Swap(int&a,int&b)
    {
        swap(a,b);
        a=-a,b=-b;
    }
    n_8 operator + (n_8 a,n_8 b)
    {
        n_8 c;
        c.w = a.w+b.w;
        chkmax(c.wl,c.pll,a.wl,a.pll,a.w+b.wl,b.pll);
        chkmax(c.wr,c.prr,b.wr,b.prr,b.w+a.wr,a.prr);
        chkmax(c.wu,c.pl,c.pr,a.wu,a.pl,a.pr,b.wu,b.pl,b.pr);
        chkmax(c.wu,c.pl,c.pr,c.wu,c.pl,c.pr,a.wr+b.wl,a.prr,b.pll);
        return c;
    }
    struct segtree
    {
        int w[N<<2],wl[N<<2],wr[N<<2],wu[N<<2],pl[N<<2],pr[N<<2],pll[N<<2],prr[N<<2];
        int _wl[N<<2],_wr[N<<2],_wu[N<<2],_pl[N<<2],_pr[N<<2],_pll[N<<2],_prr[N<<2];
        bool res[N<<2];
        void update(int u)
        {
            w[u] = w[u<<1]+w[u<<1|1];
            chkmax(wl[u],pll[u],wl[u<<1],pll[u<<1],w[u<<1]+wl[u<<1|1],pll[u<<1|1]);
            chkmax(wr[u],prr[u],wr[u<<1|1],prr[u<<1|1],w[u<<1|1]+wr[u<<1],prr[u<<1]);
            chkmin(_wl[u],_pll[u],_wl[u<<1],_pll[u<<1],w[u<<1]+_wl[u<<1|1],_pll[u<<1|1]);
            chkmin(_wr[u],_prr[u],_wr[u<<1|1],_prr[u<<1|1],w[u<<1|1]+_wr[u<<1],_prr[u<<1]);
            chkmax(wu[u],pl[u],pr[u],wu[u<<1],pl[u<<1],pr[u<<1],wu[u<<1|1],pl[u<<1|1],pr[u<<1|1]);
            chkmax(wu[u],pl[u],pr[u],wu[u],pl[u],pr[u],wr[u<<1]+wl[u<<1|1],prr[u<<1],pll[u<<1|1]);
            chkmin(_wu[u],_pl[u],_pr[u],_wu[u<<1],_pl[u<<1],_pr[u<<1],_wu[u<<1|1],_pl[u<<1|1],_pr[u<<1|1]);
            chkmin(_wu[u],_pl[u],_pr[u],_wu[u],_pl[u],_pr[u],_wr[u<<1]+_wl[u<<1|1],_prr[u<<1],_pll[u<<1|1]);
        }
        void reser(int u)
        {
            res[u]^=1;
            w[u] = -w[u];
            Swap(wl[u],_wl[u]);Swap(wr[u],_wr[u]);Swap(wu[u],_wu[u]);
            swap(pl[u],_pl[u]);swap(pr[u],_pr[u]);
            swap(pll[u],_pll[u]);swap(prr[u],_prr[u]);
        }
        void pushdown(int u)
        {
            if(res[u])
            {
                reser(u<<1);
                reser(u<<1|1);
                res[u] = 0;
            }
        }
        void build(int l,int r,int u)
        {
            if(l==r)
            {
                int x;read(x);
                w[u] = wu[u] = _wu[u] = wl[u] = _wl[u] = wr[u] = _wr[u] = x;
                pl[u]=pr[u]=pll[u]=prr[u]=_pl[u]=_pr[u]=_pll[u]=_prr[u]=l;
                return ;
            }
            int mid = (l+r)>>1;
            build(l,mid,u<<1);
            build(mid+1,r,u<<1|1);
            update(u);
        }
        void insert(int l,int r,int u,int qx,int d)
        {
            if(l==r)
            {
                w[u] = wu[u] = _wu[u] = wl[u] = _wl[u] = wr[u] = _wr[u] = d;
                return ;
            }
            pushdown(u);
            int mid = (l+r)>>1;
            if(qx<=mid)insert(l,mid,u<<1,qx,d);
            else insert(mid+1,r,u<<1|1,qx,d);
            update(u);
        }
        void erase(int l,int r,int u,int ql,int qr)
        {
            if(l==ql&&r==qr)
            {
                reser(u);
                return ;
            }
            pushdown(u);
            int mid = (l+r)>>1;
            if(qr<=mid)erase(l,mid,u<<1,ql,qr);
            else if(ql>mid)erase(mid+1,r,u<<1|1,ql,qr);
            else erase(l,mid,u<<1,ql,mid),erase(mid+1,r,u<<1|1,mid+1,qr);
            update(u);
        }
        n_8 query(int l,int r,int u,int ql,int qr)
        {
            if(l==ql&&r==qr)return n_8(w[u],wl[u],wr[u],wu[u],pl[u],pr[u],pll[u],prr[u]);
            pushdown(u);
            int mid = (l+r)>>1;
            if(qr<=mid)return query(l,mid,u<<1,ql,qr);
            else if(ql>mid)return query(mid+1,r,u<<1|1,ql,qr);
            else return query(l,mid,u<<1,ql,mid)+query(mid+1,r,u<<1|1,mid+1,qr);
        }
    }tr;
    int main()
    {
        read(n);
        tr.build(1,n,1);
        read(m);
        int op,x,y,w;
        for(int i=1;i<=m;i++)
        {
            read(op),read(x),read(y);
            if(!op)tr.insert(1,n,1,x,y);
            else
            {
                read(w);
                n_8 tmp = tr.query(1,n,1,x,y);
                int ans = 0;
                for(int j=1;j<=w;j++)
                {
                    if(tmp.wu>0)
                    {
                        ans+=tmp.wu;
                        chg[j][0]=tmp.pl,chg[j][1]=tmp.pr;
                        tr.erase(1,n,1,tmp.pl,tmp.pr);
                        tmp = tr.query(1,n,1,x,y);
                    }else
                    {
                        w = j-1;
                        break;
                    }
                }
                printf("%d
    ",ans);
                for(int j=1;j<=w;j++)
                    tr.erase(1,n,1,chg[j][0],chg[j][1]);
            }
        }
        return 0;
    }
    View Code

    压行大法好。

  • 相关阅读:
    转--后台开发人员的技术栈
    hadoop +streaming 排序总结
    python 的tempfile学习
    hadoop学习日志
    shell sort 排序大讨论
    系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式
    推荐系统评测指标--准确率(Precision)和召回率(Recall)、F值(F-Measure)
    shell 数组
    leecode第七百四十六题(使用最小花费爬楼梯)
    leecode第四百七十五题(供暖器)
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10763172.html
Copyright © 2020-2023  润新知