Problem Link

有一棵 \(n\) 个点的完全二叉树(点 \(i\) 的父亲是 \(\lfloor i/2\rfloor\)),第 \(i\) 个点有 \(a_i\) 个苹果。现在有 \(m\) 个订单,每个订单只接受 \(u_i\) 到 \(v_i\) 路径上的苹果,保证 \(u_i\) 是 \(v_i\) 的祖先,并且最多只接受 \(c_i\) 个苹果,单价为 \(w_i\)。你可以把苹果任意分给订单,求最大可能收益。

\(n,m\le 5\times 10^5\)。


技巧:费用流转 Hall 定理

我会费用流!直接从每个订单向链上的点连边,源点向订单连容量为订单上限,费用为单价的边,点向汇点连容量为苹果数的边,跑最大费用流即可!\(m\log n\) 条边,这不乱冲

当然冲不过去。考虑模拟费用流(说白了就是贪心,但是由费用流可以清楚地证明正确性),即将所有订单按单价从大到小排序,每次流的时候尽量流满即可(注意到反向边没法流)。

怎么流呢?是一个比较清奇的想法:二分一个流量,然后用别的方法判断当前流量是否合法。具体地,我们可以使用 Hall 定理!

发现给每条边钦定好流量之后,判断合不合法,就是判断是否存在一个链到苹果的匹配(前者满配),对应到 Hall 定理就是是否对于任意多条链的并,它们对应位置上的苹果数之和大于等于这些链的需求之和。

进一步,若干条链的并形成若干个连通块,显然不同连通块可以分开算。

于是考虑枚举这个连通块的根 \(r\),那么就是看是否存在一个以 \(r\) 为根的连通块,其中链和大于苹果和则不合法。可以对于每条链 \((u,v)\) 满足 \(u\) 在 \(r\) 的子树内,在 \(v\) 上打一个 \(-c_i\) 的标记,对每个节点打一个 \(+a_i\) 的标记,那么合法当且仅当每个包含根的连通块权值和均 \(\ge 0\)。这个可以用一个简单的 dp 判断:每个 \(f\) 从子树之和转移过来,然后对 \(0\) 取 \(\min\)。

修改一条链只用判断它的 \(v\) 到 \(1\) 路径上的那些根是否合法,每个根也只用重新计算 \(v\) 祖先里的那些点,所以单次时间复杂度 \(O(\log^2 n)\),总复杂度(算上二分)\(O(m\log^3 n)\)。

过不去!然后发现这个二分完全没必要,对于每个根可以直接算出所允许的最大值取个 \(\min\) 即可。

具体地,在 \(v\) 不断往上更新时,如果发现当前节点的 \(f\) 大于 \(0\),则可以在此时将链选的权值 \(x\) 增加 \(f\)。理由是反正 \(f\) 都要对 \(0\) 取 \(\min\),并且如果 \(f\le 0\),那增大 \(x\) 必然减小 \(f\),欠的总是要还的,不如将来再加。

这样总时间复杂度就 \(O(m\log^2 n)\) 了。

点击查看代码
#include <bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Rev(i,a,b) for(int i=a;i>=b;i--)
#define Fin(file) freopen(file,"r",stdin);
#define Fout(file) freopen(file,"w",stdout);
using namespace std;
const int N=1e5+5; typedef long long ll;
struct Node{int u,v,c,w;bool operator<(const Node& rhs)const{return w>rhs.w;}}O[N];;
int n,m,a[N]; ll f[N][18],g[N][18];
ll work(int o,int v){
ll res=0; int z=__lg(o);
for(int k=v;k>=o;k>>=1){
int k1=k<<1,k2=k<<1|1; k1>n&&(k1=0); k2>n&&(k2=0);
res+=max(0ll,f[k1][z]+f[k2][z]+a[k]-g[k][z]);
}
return res;
}
void update(int o,int v,ll x){
int z=__lg(o); g[v][z]+=x;
for(int k=v;k>=o;k>>=1){
int k1=k<<1,k2=k<<1|1; k1>n&&(k1=0); k2>n&&(k2=0);
f[k][z]=min(0ll,f[k1][z]+f[k2][z]+a[k]-g[k][z]);
}
assert(f[o][z]>=0);
}
void solve(){
cin>>n>>m; For(i,1,n) cin>>a[i];;
For(i,0,n) memset(f[i],0,sizeof(f[i])),memset(g[i],0,sizeof(g[i]));
For(i,1,m) cin>>O[i].u>>O[i].v>>O[i].c>>O[i].w;; sort(O+1,O+1+m);
ll ans=0;
For(i,1,m){
auto [u,v,c,w]=O[i];
ll x=c; for(int o=u;o;o>>=1) x=min(x,work(o,v));
ans+=x*w; for(int o=u;o;o>>=1) update(o,v,x);
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0); cin.tie(0);
int T; cin>>T; while(T--) solve();
return 0;
}

【网络流,dp】Gym102220A Apple Business的更多相关文章

  1. 【树形dp】Apple Tree

    [poj2486]Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10800   Accepted: 3 ...

  2. POJ3176-基础DP

    很基础的dp题.有一头奶牛想接尽量多的苹果,有w此移动机会. dp[i][w] = max(dp[i-1][w+1] + 能否吃到苹果 ,dp[i-1][w] + 能否吃到苹果)  //从上一分钟是否 ...

  3. The 13th Chinese Northeast Collegiate Programming Contest

    题解: solution Code: A. Apple Business #include<cstdio> #include<algorithm> #include<ve ...

  4. QDEZ集训笔记【更新中】

    这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...

  5. 较具体的介绍JNI

    JNI事实上是Java Native Interface的简称,也就是java本地接口.它提供了若干的API实现了和Java和其它语言的通信(主要是C&C++).或许不少人认为Java已经足够 ...

  6. 更具体的描述JNI

    JNI事实上,Java Native Interface缩写,也就是说,java本地接口. 它提供了许多API实现和Java并与其他语言的沟通(主要C&C++). 也许很多人认为Java够劲. ...

  7. POJ2385--Apple Catching(动态规划)

    It is a little known fact that cows love apples. Farmer John has two apple trees (which are convenie ...

  8. 较详细的介绍JNI

    JNI其实是Java Native Interface的简称,也就是java本地接口.它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++).也许不少人觉得Java已经足够强 ...

  9. BZOJ 1221: [HNOI2001] 软件开发【最小费用最大流】

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

  10. Distributing Custom Apps

    Distributing Custom Apps 分配自定义应用程序 November 10, 2020 2020年11月10日 Custom apps let you meet the unique ...

随机推荐

  1. “互联网+”大赛之AI创新应用赛题攻略:大胆脑洞,共绘智慧生活蓝图

    摘要:本次"互联网+"大赛AI创新应用赛题的设置是希望学生可以从日常实际应用需求出发,结合自己的奇思妙想,提升智能终端用户的使用体验,为构建万物互联的智能世界贡献一份力量. 本文分 ...

  2. 云小课 | SA基线检查—给云服务的一次全面“体检”

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要: 华为云态势感知( ...

  3. Windows 2012 上网慢如何解决

    解决步骤:1.执行netsh  int  tcp  show  global 查看默认TCP全局参数等相关设置 Windows 2012 默认ECN 功能是开启的,将其关闭即可 以管理员的身份运行下列 ...

  4. BOM批量查询

     1业务要求 1.当多层展开时: 根据"BOM应用程序"字段CAPID在TC04中取出"选择ID"TC04-CSLID: 再根据TCS41-CSLID= TC0 ...

  5. Hottest 30 of codeforce

    1. 4A.Watermelon 题目链接:https // s.com/problemset/problem/4/A 题意:两人分瓜,但每一部分都得是偶数 分析:直接 对2取余,且 w != 2 # ...

  6. Educational Codeforces Round 94 (A - D题题解)

    https://codeforces.com/contest/1400/problem/A Example input 4 1 1 3 00000 4 1110000 2 101 output 1 0 ...

  7. 第三届云原生编程挑战赛正式启动,Serverless 赛道邀你参加!

    据<云原生开发现状报告>显示,全球云原生开发人员达 680 万,与 2020 年 5 月报告的云原生开发者数量 470 万相比,全球云原生开发人员数量正极速增长,越来越多开发者加入到云原生 ...

  8. uni-app点赞效果

  9. freeswitch修改mod_sofia模块并上报自定义头域

    概述 在之前的文章中,我们介绍了如何使用fs的event事件机制来获取呼叫的各种信息. 这些event事件一般都是底层模块定义好的,其中的各种信息已经很完备了,日常的开发需求都可以满足. 但是,总有一 ...

  10. socket TCP DPT 网络编程

    复习: ARP协议: 广播和单播 通过ip地址获得mac地址 机器A发起一个arp请求(只包含A的ip地址) 交换机接收到请求,广播这条消息 所有的机器都会接受到这条请求,只有需要寻找的机器B的ip地 ...