zoukankan      html  css  js  c++  java
  • #455. 【UER #8】雪灾与外卖

    题目

    先按左边排,考虑一个人/店不是匹配左边的(主动)就是让右边的匹配他(被动)

    定义 $v$ 为堆顶(小根堆),至于是人堆还是店堆按具体情况。

    一个人匹配某家店

    匹配左边: $x+v$,那么 $v=w-y$。这里显然是店堆。

    匹配右边:反悔,$-(x+v)-x$ 插入人堆。具体为什么插入这个东西下面会提到。

    店匹配人(也就是人匹配右边的店,假如花费大于0,那么一定不优于让人匹配左边)

    匹配左边:$w+y+v$ 的形式,那么实际上就是要 $v=-x$ ,至于 $-(x+v)$ 是为了撤销匹配左边的贡献。

    匹配右边:$-(w+y+v)-y+w$ 因为考虑人匹配左边的店是 $x+v$,那么撤销这次店的匹配就是 $-(w+y+v)$,实际上 $x+v=x-y+w$。

    但假如是店2匹配店1所匹配的人呢? 即可能相邻2个店。我们考虑将店1当人看。

    设 $y1,w1,y2,w2,v$

    那么店1匹配的人就是 $w1+y1+v$,那假如让店2替代,还需要花费 $(w2+y2+v)-(w1+y1+v)=w1+y1-w2-y2$,对照下店匹配人的式子,$y+w+v$,则$v=-y2-w2$,即往人堆插入 $-y-w$ 即可。

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
     
    #define ll long long
     
    using namespace std;
    int rd() {
        int f=1,sum=0; char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return sum*f;
    }
    ll lrd() {
        ll f=1,sum=0; char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return sum*f;
    }
    
    const int N=(int)(1e5+5);
    struct node {
        mutable ll v,tot;
        bool operator < (const node &x) const {
            return v>x.v;
        }
        bool operator > (const node &x) const {
            return v<x.v;
        }
    };
    #define min(X,Y) (X>Y?Y:X)
    const ll inf=0x7fffffff;
    priority_queue<node>q1,q2;
    ll ans;
    int X[N],Y[N],W[N],C[N],n,m;
    
    void ins1(int id) {
        ll qwq=inf;
        if(!q2.empty()) {
            node x=q2.top();
            qwq=X[id]+q2.top().v; 
            if(!(--q2.top().tot)) q2.pop();
        }
        ans+=qwq; q1.push((node){-qwq-X[id],1});
    }
    
    void ins2(int id) {
        int tot=0; ll res=0;
        while(!q1.empty()&&tot<C[id]) {
            ll qwq=q1.top().v+W[id]+Y[id];
            if(qwq>=0) break;
            int cnt=min(q1.top().tot,C[id]-tot);
            ans+=qwq*cnt; tot+=cnt;
            q2.push((node){-qwq-Y[id]+W[id],cnt});
            if(!(q1.top().tot-=cnt)) q1.pop();
        }
        if(tot) q1.push((node){-Y[id]-W[id],tot});
        if(C[id]-tot) q2.push((node){-Y[id]+W[id],C[id]-tot});
    }
    
    int main() {
        n=rd(); m=rd(); ll qwq=0;
        for(int i=1;i<=n;i++) X[i]=rd();
        for(int i=1;i<=m;i++) Y[i]=rd(),W[i]=rd(),C[i]=rd(),qwq+=C[i];
        if(qwq<n) {
            puts("-1"); return 0;
        }
        int j=1;
        for(int i=1;i<=m;i++) {
            while(j<=n&&X[j]<=Y[i]) ins1(j++);
            ins2(i);
        }
        while(j<=n) ins1(j++);
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    [转]MNIST机器学习入门
    nvidia tesla k40
    [转]LeNet-5结构分析及caffe实现————卷积部分
    caffe
    [转]CNN的学习
    Mysql常用命令记录
    jaxb xml to bean
    吸血鬼数字算法参考 -- javascript版本
    jQuery input -> file change事件bug
    Jetty
  • 原文地址:https://www.cnblogs.com/xugangfan/p/15129852.html
Copyright © 2011-2022 走看看