题目来源
简述
- 一共发送2k-1条信息
- 前k条信息,第i个信息含有i个内容
- 从第k+1条信息开始 第i个信息含有2k-i个内容
- 给定一个x,当内容大于等于x时拦截
- 问发送到第几条信息时拦截
解析
- 这是一条二分法的题目
- 需要用的前n项和公式(记为cnt)
- 当i<=k时,计算比较x的方法用公式cnt(i)
- 当i>k时,计算比较x的方法为cnt(k)+cnt(k-1)-cnt(2k-1-y)
- 二分法,设置初始区间段l=1,r=2k-1。mid=(l+r)/2
- 如果mid小于x,则说明答案在区间的右半部分,则设置l=mid+1,并更新了res=mid
- 如果mid大于x,则说明答案在区间的左半部分,则设置r=mid-1
- 最终当区间长度为1时,输出这个答案
代码段
ll get(ll x)
{
return x * 1ll * (x + 1) / 2;
}
void solve()
{
int k;
ll x;
cin >> k >> x;
ll l = 1, r = 2 * k - 1;
ll res = 2 * k - 1;
bool over = 0;
while (l <= r)
{
int mid = (l + r) >> 1;
if (mid >= k)
{
over = (get(k) + get(k - 1) - get(2 * k - 1 - mid) >= x);
}
else
{
over = (get(mid) >= x);
}
if (over)
{
res = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
cout << res << endl;
}