解题思路
将能量值从小到大排序。固定选取数量 和选中元素的最大下标 ,最优目标值为 。若选中了 之前的元素,则区间 内必有未选中的元素。用后者替换前者,操作次数不会增加。因此,仅需考虑连续区间。
设区间 的元素和为 ,将其全部增加到 的代价为:
固定 ,右移 时,原有元素的目标值不会降低,新元素无需操作,故代价不减。于是依次枚举 ,若代价超过 ,便右移 ,直到区间可行。被舍弃的左端点以后仍不可行,故此时的 是以 为右端点的最长可行区间。取所有区间长度的最大值即可。
两个指针均至多移动 次,总时间复杂度为 。代价不超过 ,使用 long long。
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=500005;
ll a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
ll m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
int l=1,ans=0;
ll sum=0;
for(int i=1;i<=n;i++)
{
sum+=a[i];
while(a[i]*(i-l+1)-sum>m)
{
sum-=a[l];
l++;
}
ans=max(ans,i-l+1);
}
cout<<ans<<'\n';
return 0;
}