【ARC106E】 Medals 【网络流】【最小割】【FWT】

题意

N N N个人( N ≤ 18 N\leq 18 N18),第 i i i个人出现 A i A_i Ai天然后消失 A i A_i Ai天( A i ≤ 1 0 5 A_i\leq 10^5 Ai105),循环下去。每天可以给某一个出现的人发一块奖牌,问最少要多少天才能让任意一个人都有至少 K K K块奖牌( K ≤ 1 0 5 K\leq 10^5 K105)。

分析

首先二分答案,这样就转化为了一个判定性问题。
考虑一个简单的网络流建模, S S S向每个人连一条容量为 K K K的边,每个人向他出现的一天连一条容量为 1 1 1的边,每一天向 T T T连一条容量为 1 1 1的边。这样只要最大流满流就有解了。
考虑到人数很小,可以把所有天分成 2 N 2^N 2N类,代表每个人是否在这一天出现。这样我们就可以把同一类的若干天合并成一个点,向 T T T连一条容量为这一类天的总数的边。
考虑答案的范围。显然答案 ≥ N K \geq NK NK。按顺序给每一个人发 K K K块奖牌,每个人至多花费 2 K 2K 2K天,因此答案的一个上界是 2 N K 2NK 2NK,只有 3.6 × 1 0 6 3.6\times10^6 3.6×106级别。因此我们可以预处理出每一天是属于哪一类的。
考虑怎样快速计算这个网络流。把网络流转化为最小割来考虑,相当于在左边割掉一些人,右边割掉一些天使得 S S S T T T不联通。如果一个人没有被左边割掉,那右边包含这个人的所有天必须被割掉。因此我们可以枚举左边割掉了哪些人,这样右边割掉的天就已经确定下来了,不难发现右边割掉的边的权值和是一个子集和的形式,可以通过 F W T FWT FWT求高维前缀和在 2 N N 2^NN 2NN的时间复杂度内预处理出来。判断最小割是否为 N K NK NK即可。
时间复杂度: 2 N N log ⁡ ( N K ) 2^NN\log(NK) 2NNlog(NK)

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=20,M=1050005;
int n,m,k,l,r,mid,ans,a[N],b[M],c[M],sta[N*M];
bool check(){
	for(int i=0;i<m;i++){
		b[i]=0;
		c[i]=c[i>>1]+(i&1);
	}
	for(int i=0;i<mid;i++){	
		b[sta[i]]++;
	}
	for(int i=1;i<m;i<<=1){
		for(int j=0;j<m;j+=(i<<1)){
			for(int k=j;k<j+i;k++){
				b[k+i]+=b[k];
			}
		}
	}
	int res=n*k;
	for(int i=0;i<m;i++){
		if(b[m-1]-b[i]+c[i]*k<res){
			return false;
		}
	}
	return true;
}
int main(){
	scanf("%d%d",&n,&k);
	m=1<<n;
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	l=n*k,r=2*n*k,ans=r;
	for(int i=0;i<r;i++){
		for(int j=0;j<n;j++){
			if(~(i/a[j])&1){
				sta[i]|=1<<j;
			}
		}
	}
	while(l<=r){
		mid=(l+r)/2;
		if(check()){
			ans=mid;
			r=mid-1;
		}else{
			l=mid+1;
		}
	}
	printf("%d\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值