专栏文章
CF760B
CF760B题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miorwb45
- 此快照首次捕获于
- 2025/12/03 00:08 3 个月前
- 此快照最后确认于
- 2025/12/03 00:08 3 个月前
你好。
题面
分 个物品给排成一排的 人,求第 个人可以拿到的最大物品数,要求相邻的人物品数相差不超过 ,且每个人都有物品。
题解
二分第 个人可以拿到的物品数 。
若第 个人拿到 个物品,则可以构造出一种方案,使得这一排人拿到的物品数最小。
如果第 个人拿到 个物品,那么第 和 人可以拿到 或 或 个物品。
由此我们可以这样构造:第 个人拿到的最多,然后区间 从 到 递减,区间 从 到 递减,当递减到 时重复。
显而易见这样构造可以使得拿到物品数最小。
设这个最小值为 。
且 在所有满足 中的 最大时, 也达到合法最大。
然后就可以这样二分了。
时间复杂度 。
代码
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,k;
ll l,r;
bool check(ll x) {
ll b,c;
if(x-(n-k)<=0) b=x*(x-1)/2+1-(x-(n-k));
else b=(x-1+x-(n-k))*(n-k)/2;
if(x-(k-1)<=0) c=x*(x-1)/2+1-(x-(k-1));
else c=(x-1+x-(k-1))*(k-1)/2;
//等差数列求和公式来求[1,k-1]和[k+1,n]贡献
return b+c+x<=m;
}
int main() {
scanf("%lld%lld%lld",&n,&m,&k);
l=1,r=m;
while(l<r) {
int mid=(l+r+1)/2;
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%lld",l);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...