牛客小白月赛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;
} 
View Code

 

posted @ 2021-09-10 21:31  starlightlmy  阅读(125)  评论(0)    收藏  举报