Processing math: 100%

洛谷P4343 [SHOI2015]自动刷题机

题目

易得该题目中的nk具有单调性,满足二分的性质,因此该题目而已用二分来枚举n,然后对于每个n模拟出它所对应的k,然后注意注意代码细节,并且当当前k等于题目要求的k时,要分别向左和右二分,才能找出所有情况。

#include <bits/stdc++.h>
#define N 3000011   
#define int long long
using namespace std;
int n, k, x[N], sum[N], maxn, minn = 2147483647124544;
int check(int mid)
{
 	int l = 1, now = 0, tot = 0;
 	while (l <= n)//这里是不能二分的,因为不满足二分单调性。 
 	{
 		while (now < mid && l <= n)
 		{
 			now += x[l++];
 			now = max(now, 0LL);
 		}	
	 	if (now >= mid)	
 		tot++, now = 0;//此处l不能++, 因为循环里已经++了 
 	}
 	return tot;
}	
signed main()
{	
 	scanf("%lld%lld", &n, &k);  
 	for (int i = 1; i <= n; i++)
 	{
 		scanf("%lld", &x[i]); 
 	 	sum[i] = sum[i - 1] + x[i];
	 	if (sum[i] < 0) sum[i] = 0;
 	}
// 	printf("%lld ", check(3));
 	int l = 1LL, r = 1000000000000LL;//二分n
 	while (l <= r)
 	{
 		int mid = (l + r) >> 1;
 		if (check(mid) > k)//如果最终的结果比k大,n越大,k越小 
 			l = mid + 1;
	 	if (check(mid) < k)
	 		r = mid - 1;
	 	if (check(mid) == k)
	 	{
	 		minn = min(minn, mid), maxn = max(maxn, mid); 
	 		r = mid - 1;
 	 	}
 	}
 	l = 1LL, r = 1000000000000LL;
 	while (l <= r)
 	{
 		int mid = (l + r) >> 1;
 		if (check(mid) > k)//如果最终的结果比k大,n越大,k越小 
 			l = mid + 1;
 	 	if (check(mid) < k)
 	 		r = mid - 1;
 	 	if (check(mid) == k)
 	 	{
 	 		minn = min(minn, mid), maxn = max(maxn, mid); 
 	 		l = mid + 1;
 	 	}
 	}
 	if (minn == 2147483647124544)
 		printf("-1"), exit(0);
 	printf("%lld %lld", minn, maxn);
 	return 0;
}	
posted @   DAGGGGGGGGGGGG  阅读(247)  评论(0编辑  收藏  举报
编辑推荐:
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 为什么构造函数需要尽可能的简单
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 大模型 Token 究竟是啥:图解大模型Token
· 35岁程序员的中年求职记:四次碰壁后的深度反思
阅读排行:
· 基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
· 电商平台中订单未支付过期如何实现自动关单?
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 上周热点回顾(3.31-4.6)
· 爆肝 1 周,为我的白板工具支持了 mermaid 流程图,为 ai 生成流程图铺平道路
点击右上角即可分享
微信分享提示