二分样例不过求调
查看原帖
二分样例不过求调
524369
netlify楼主2024/11/12 20:56
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+1;
int T,n,m,v,a[N],sum[N],pre[N],suf[N];
signed main(){
	for(cin>>T;T--;){
		cin>>n>>m>>v;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			sum[i]=sum[i-1]+a[i];
			pre[i]=suf[i]=0;
		}
		for(int i=1;i<=n;i++){
			int l=0,r=n+1,mid;
			while(l+1<r)
				mid=l+r>>1,(sum[i]-sum[mid-1]>=v)?l=mid:r=mid;
			if(sum[i]-sum[l-1]>=v)pre[i]=pre[l-1]+1;
		}
		for(int i=n;i;i--){
			int pos=lower_bound(sum+1,sum+n+1,v+sum[i-1])-sum;
			if(sum[pos]-sum[i-1]>=v)suf[i]=suf[pos+1]+1;
		}
		if(pre[n]<m){
			cout<<"-1\n";
			continue;
		}
		int ans=0;
		for(int i=1;i<=n;i++){
			int pos=lower_bound(suf+1,suf+n+1,m-pre[i],greater<int>())-suf;
			if(pre[i]+suf[pos]>=m)
				ans=max(ans,sum[pos-1]-sum[i]);
		}
		cout<<ans<<"\n";
	}
	return 0;
}

思路是二分预处理出 pre[i]pre[i] 表示只选前 ii 个数能满足多少生物,suf[i]suf[i] 同理。然后枚举 ii ,二分求出最大的 jj 使得 pre[i]+suf[j]>=mpre[i]+suf[j]>=m 然后统计答案。

2024/11/12 20:56
加载中...