zoukankan      html  css  js  c++  java
  • luogu P5331 [SNOI2019]通信

    传送门

    有匹配次数限制,求最小代价,这显然是个费用流的模型.每个点暴力和前面的点连匹配边,边数是(n^2)的.

    然后发现可以转化成一个set,每次加入一个点,然后入点对set里面的出点连边.这个set可以用主席树实现,然后就主席树优化连边,点数边数都是(nlogn)的,然后就能过了

    注意这里连边要把一个点入点拆成两个(a_i,-a_i),出点同理,然后假设(a_i)在set的第(p)位,(a_i)在负权值主席树上连区间([1,p-1]),(-a_i)在正权值主席树上连区间([p+1,n])

    然后主席树被分治连边吊打

    // luogu-judger-enable-o2
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=1e3+10,M=3e4+10,inf=1<<29;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[M<<2],nt[M<<2],c[M<<2],hd[M],tot=1;
    LL w[M<<2];
    void add(int x,int y,int z,LL zz)
    {
        if(!y) return;
        ++tot,to[tot]=y,nt[tot]=hd[x],c[tot]=z,w[tot]= zz,hd[x]=tot;
        ++tot,to[tot]=x,nt[tot]=hd[y],c[tot]=0,w[tot]=-zz,hd[y]=tot;
    }
    LL ans,di[M];
    int n,W,a[N],b[N],p[N];
    bool cmp(int aa,int bb){return a[aa]<a[bb];}
    int ps,pt,fw[M],pr[M];
    bool v[M];
    queue<int> q;
    bool csfl()
    {
        memset(di,0x3f,sizeof(LL)*(pt+3));
        di[ps]=0,v[ps]=1,q.push(ps);
        fw[pt]=0;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=hd[x];i;i=nt[i])
            {
                int y=to[i];
                if(c[i]>0&&di[y]>di[x]+w[i])
                {
                    di[y]=di[x]+w[i],fw[y]=1,pr[y]=i;
                    if(!v[y]) v[y]=1,q.push(y);
                }
            }
            v[x]=0;
        }
        if(!fw[pt]) return 0;
        ans+=di[pt];
        int x=pt;
        while(x!=ps)
        {
            int i=pr[x];
            c[i]-=fw[pt],c[i^1]+=fw[pt];
            x=to[i^1];
        }
        return 1;
    }
    int rt1,rt2,ch[M][2],t1,t2;
    void inst(int o1,int o2,int x,int &tt)
    {
        int l=1,r=n;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(x<=mid)
            {
                ch[o1][0]=++tt,ch[o1][1]=ch[o2][1];
                add(o1,ch[o1][0],inf,0),add(o1,ch[o1][1],inf,0);
                o1=ch[o1][0],o2=ch[o2][0];
                r=mid;
            }
            else
            {
                ch[o1][0]=ch[o2][0],ch[o1][1]=++tt;
                add(o1,ch[o1][0],inf,0),add(o1,ch[o1][1],inf,0);
                o1=ch[o1][1],o2=ch[o2][1];
                l=mid+1;
            }
        }
    }
    void link(int o,int l,int r,int ll,int rr,int x,int y)
    {
        if(!o) return;
        if(ll<=l&&r<=rr){add(x,o,1,y);return;}
        int mid=(l+r)>>1;
        if(ll<=mid) link(ch[o][0],l,mid,ll,rr,x,y);
        if(rr>mid) link(ch[o][1],mid+1,r,ll,rr,x,y);
    }
    
    int main()
    {
        n=rd(),W=rd();
        ps=0,pt=n*24+2;
        t1=n*2,t2=n*13;
        for(int i=1;i<=n;++i) a[i]=rd(),b[i]=i;
        sort(b+1,b+n+1,cmp);
        for(int i=1;i<=n;++i) p[b[i]]=i;
        for(int i=1;i<=n;++i)
        {
            add(ps,i,1,0),add(i,pt,1,W);
            int las;
            las=rt1,rt1=++t1,inst(rt1,las,p[i],t1);
            las=rt2,rt2=++t2,inst(rt2,las,p[i],t2);
            if(p[i]>1) link(rt1,1,n,1,p[i]-1,i,a[i]);
            if(p[i]<n) link(rt2,1,n,p[i]+1,n,i,-a[i]);
            add(t1,i+n,1,-a[i]),add(t2,i+n,1,a[i]);
            add(i+n,pt,1,0);
        }
        while(csfl());
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    [BZOJ 1019][SHOI2008]汉诺塔(递推)
    [BZOJ 1018][SHOI2008]堵塞的交通traffic(线段树)
    [BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
    [BZOJ 1015][JSOI2008]星球大战starwar(并查集+离线)
    [BZOJ 1014][JSOI2008]火星人prefix(Splay+二分+hash)
    Vue脚手架创建项目目录详解
    Vue-cli3 vue.config.js配置详解
    Systemd指令大全
    CentOS7 常用命令集合
    Centos7虚拟机集群配置
  • 原文地址:https://www.cnblogs.com/smyjr/p/10802005.html
Copyright © 2011-2022 走看看