1 条题解
-
0
自动搬运
来自洛谷,原作者为

Fyq_20
**搬运于
2025-08-24 23:10:47,当前版本为作者最后更新于2025-03-10 14:45:49,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题解:[TOIP 2023]裁员风暴
题目大意:
在给定数组 中,找到所有 和 中的第 大的数。
主要思路:二分答案+双指针判定
首先将选择一个的情况视为选择了两个一样的数,这样题目就变成了在 中找到所有 中的第 大的数。
先确定主算法是二分,然后考虑如何求比一个数 大的 的个数。
容易想到首先给数组排序,得到单调不降的数组,然后枚举左界 ,此时可以使 的最大右界 在 增加时不会增加(,即比 小的数集为 时除外)。于是在枚举 时实时更新 ,并得到较小数为 时比 大的 的个数 ,此时 就是比 大的 的个数。最后正常二分答案,特判分子是否可以被 整除分别输出即可。注意如果二分的是答案的 倍需要开
long long。code:
#include<bits/stdc++.h> using namespace std; #define int long long//不是什么好习惯 int n,k; int p[200005]; bool check(int x) { int pos=0; int l=1,r=n; for(l;l<=n;l++) { if(r<l)r=l-1; //注意如果之前r被更新到小于l //需要赋值为l-1 //否则会计重。 while(p[l]+p[r]>=x&&r>=l)r--; pos+=n-r; } return pos<k; } signed main() { cin>>n>>k; for(int i=1;i<=n;i++)cin>>p[i]; sort(p+1,p+n+1); int l=-2e9,r=2e9;//这里二分的是答案的2倍 while(l<r) { int mid=l+r+1; mid>>=1; if(check(mid))r=mid-1; else l=mid; } if(l%2==0)cout<<l/2<<endl<<1<<endl; else cout<<l<<endl<<2<<endl;//特判l和2互质 return 0; }
- 1
信息
- ID
- 11610
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者