社区讨论

能否用wqs二分做

CF2061EKevin and And参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mmixnu1w
此快照首次捕获于
2026/03/09 16:42
昨天
此快照最后确认于
2026/03/09 21:28
21 小时前
查看原帖
RT,感觉显然的凸单调性,但一直WA第二个点,答案偏大。
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 200100
int T,n,m,k,a[N],b[N],f[N][21],Cnt,ans;
int check(int x){
	Cnt=0;int sum=0;
	for(int i=0;i<n;i++){
		int mnv=a[i],id=0;
		for(int j=1;j<=m;j++){
			if(f[i][j]+x*j<mnv)
				mnv=f[i][j]+x*j,id=j;
		}
		sum+=mnv,Cnt+=id;
	}
	if(Cnt>k)return -1;
	return sum;
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n>>m>>k;
		for(int i=0;i<n;i++)cin>>a[i];
		for(int i=0;i<m;i++)cin>>b[i];
		for(int i=0;i<n;i++)
			for(int j=0;j<=m;j++)
				f[i][j]=a[i];
		ans=0;for(int i=0;i<n;i++)ans+=a[i];
		if(!k){cout<<ans<<'\n';continue;}
		for(int s=0;s<(1<<m);s++){
			int cnt=0,t=(1ll<<32)-1;
			for(int i=0;i<m;i++)
				if((s>>i)&1)++cnt,t&=b[i];
			for(int i=0;i<n;i++)f[i][cnt]=min(f[i][cnt],t&a[i]);
		}
		int l=-3e9,r=3e9,d=check(0);
		if(d!=-1){cout<<d<<'\n';continue;}
		while(l<=r){
			int mid=(l+r)>>1;
			int t=check(mid);
			if(t==-1)l=mid+1;
			else ans=t-Cnt*mid,r=mid-1;
		}
		cout<<ans<<'\n';
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...