原题链接
题意:
小红拿到了一个长度为n的数组。她每次操作可以让某个数加 1 或者某个数减 1 。
小红最多能进行k次操作。她希望操作结束后,该数组出现次数最多的元素次数尽可能多。
你能求出这个最大的次数吗?
思路:
固定ai让左右的数往ai靠,然后二分区间长度或者双指针遍历区间,前缀和O1算区间贡献,不错的思维题。
二分
#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 998244353
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
typedef pair<int,int>pa;
const int N = 3e5+7;
LL a[N], sum[N], n, k, ans;
char s[N];
bool check(LL x){
for(int l = 1;l+x-1 <= n;l++){
LL r = l+x-1;
LL mid = l+r>>1;
if(a[mid]*(mid-l+1)-(sum[mid]-sum[l-1]) + sum[r]-sum[mid]-a[mid]*(r-mid) <= k){
return true;
}
}
return false;
}
int main(){
int m, _;
scanf("%lld%lld", &n, &k);
for(int i = 1;i <= n;i++){
scanf("%lld", &a[i]);
}
sort(a+1, a+1+n);
for(int i = 1;i <= n;i++){
sum[i] = sum[i-1]+a[i];
}
LL l = 1, r = n<<1;
while(l<=r){
LL mid = l+r>>1;
if(check(mid)){
ans = mid;
l = l+1;
}
else r = mid-1;
}
printf("%lld\n", ans);
return 0;
}
双指针
#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 998244353
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
typedef pair<int,int>pa;
const int N = 3e5+7;
LL a[N], sum[N], n, k, ans;
char s[N];
int main(){
int m, _;
scanf("%lld%lld", &n, &k);
for(int i = 1;i <= n;i++){
scanf("%lld", &a[i]);
}
sort(a+1, a+1+n);
for(int i = 1;i <= n;i++){
sum[i] = sum[i-1]+a[i];
}
LL l = 1, r = 2, ans = 1;
while(l<=n && r<=n){
LL mid = l+r>>1;
if(a[mid]*(mid-l+1)-(sum[mid]-sum[l-1]) + sum[r]-sum[mid]-a[mid]*(r-mid) <= k){
ans = max(ans, r-l+1);
r++;
}
else l++;
}
printf("%lld\n", ans);
return 0;
}