牛客小白月赛37 I-加减
链接:https://ac.nowcoder.com/acm/contest/11214/I
思路(关于区间问题的简单思考):
当无法解决问题时,可尝试固定一个端点,考虑另一端的单调性
如果满足单调性,可将时间复杂度从O(n^2)变成O(nlogn)
code:
#include<bits/stdc++.h> #define ll long long using namespace std; ll k,n; ll a[100005]; ll pre[100005]; ll solve(int l,int r){ int mid=(l+r)>>1; return pre[r]-pre[mid]-pre[mid-1]+pre[l-1]-a[mid]*(r-mid)+a[mid]*(mid-l); } int main(){ cin>>n>>k; pre[0]=0; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+n+1); for(int i=1;i<=n;i++) pre[i]=pre[i-1]+a[i]; int ans=0; for(int i=1;i<=n;i++){ int l=i,r=n; //考虑区间[l,r],对于给定的l,一定存在一个r使得这个区间正好能符合要求 while(l<=r){ int mid=(l+r)>>1; if(solve(i,mid)<=k) l=mid+1,ans=max(ans,mid-i+1); else r=mid-1; } } cout<<ans<<endl; return 0; }

浙公网安备 33010602011771号