首页 > 其他分享 >【网络流,dp】Gym102220A Apple Business

【网络流,dp】Gym102220A Apple Business

时间:2023-07-20 19:58:01浏览次数:50  
标签:Apple Business min int ll k2 k1 苹果 dp

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;
}


标签:Apple,Business,min,int,ll,k2,k1,苹果,dp
From: https://www.cnblogs.com/Charlie-Vinnie/p/17569474.html

相关文章

  • 网络编程 p5 UDP编程
    UDP网络通信编程基本介绍类DatagramSocket和DatagramPacket实现了基于UDP协议网络程序。UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。DatagramPacket对象封装了UDP数据报,在数据报中包含了发......
  • 20230719-动态规划DP
    20230719数位DPP4127[AHOI2009]同类分布题目描述传送门求出[a,b]中各位数字之和能整除原数的数的个数\(a,b≤1e18\)Solution对于这种求是否能整除的题我们只有在最后才能得到答案这道题很明显是数位DP考虑用记忆化搜索来实现对于每一位我们需要维护前面的数字之......
  • acwing选数异或 dp
    题目链接:https://www.acwing.com/problem/content/description/4648/题解链接[转载]:https://www.acwing.com/solution/content/137064/1#include<iostream>2#include<algorithm>3#include<vector>4#include<string>5#include<queue>......
  • TCP和UDP协议的区别
    1、TCP是面向连接的,而UDP是无连接的协议。2、TCP对于传输有用的数据非常可靠,因为它需要确认发送的信息,并且能重新发送丢失的数据包;UDP是一种不可靠的协议,数据包丢失,它不会请求重新传输,目标计算机会收到损坏的数据3、TCP速度较慢,但更健壮,因为TCP在传输数据之前建立连接,并确保数据......
  • python udp settimeout
    PythonUDPsettimeout实现步骤为了帮助你理解和实现Python的UDPsettimeout功能,我将提供以下步骤。首先,我们将了解UDP和settimeout的概念,然后讨论如何在Python中使用它们。UDP简介UDP(UserDatagramProtocol)是一种无连接的传输协议,它在网络中负责将数据包从一个主机发送到另一......
  • python threadpool
    Python线程池详解在并发编程中,线程池是一种常见的设计模式,它可以提高程序的性能和响应能力。Python中有许多库可以实现线程池,其中最常用的是concurrent.futures模块中的ThreadPoolExecutor类。本文将介绍Python线程池的工作原理、使用方法和一些示例代码。什么是线程池?线程池是......
  • Matlab马尔可夫区制转换动态回归模型估计GDP增长率|附代码数据
    原文链接:http://tecdat.cn/?p=19918最近我们被客户要求撰写关于马尔可夫区制转换动态回归的研究报告,包括一些图形和统计输出。本文估计实际GDP增长率的两状态Markov区制转换动态回归模型  ( 点击文末“阅读原文”获取完整代码数据******** )。创建模型进行估计通过指定转移......
  • 20230705-动态规划DP 2
    20230705单调队列优化DPHDU3401Trade题目大意传送门有T天,第i天买股票花Api元,卖股票花Bpi元,最多能买Asi股,能卖Bsi股。任何时候股票持有量不得超过MaxP,且两个交易日至少要间隔W天。若开始时有无限块钱,最后最多能赚多少钱?(你都有无限块钱了怎么赚都不会增加啊)0<=W<T<......
  • 20230703-动态规划DP 1
    20230703热身题目求长度为n的合法括号序列有多少个,对\(10^9+7\)取模。\(n\)为偶数,\(n\le10^6\)。Solution可以维护一个栈遇到一个左括号就加入栈而遇到右括号时就取栈顶的左括号与它配对出栈一个合法序列需要保证:最后栈为空,即所有的左括号都和有括号配对了中间不能出......
  • WordPress数据表结构
    如果是一个普通的用户,不需要了解wordpress数据库的结构。但是,如果你正在写一个插件,你应该会对wordpress如何处理它的数据和关系感兴趣。如果你已经尝试使用已经存在的wordpressapi去访问你需要的数据,但不直接访问数据库的情况下,这是不可能的,WordPress的提供WPDB的类,使这项任务变......