zoukankan      html  css  js  c++  java
  • Codeforces 1244E Minimizing Difference (二分答案)

    链接:https://codeforces.com/problemset/problem/1244/E

    题意:长度为n的序列,k次操作,每次可将任意一个数加一或减一,问k次操作后 最小的 最大值和最小值的差是多少

    题解:很明显,序列在向中间收缩, 答案满足单调性,可二分答案,分别暴力枚举最大值和最小值,查询上下界,判断是否能在k次内完成。复杂度nlogn*logn

    #include <bits/stdc++.h>
    #define IO_read ios::sync_with_stdio(false);cin.tie(0)
    #define fre freopen("in.txt", "r", stdin)
    #define _for(i,a,b) for(int i=a; i< b; i++)
    #define _rep(i,a,b) for(int i=a; i<=b; i++)
    #define lowbit(a) ((a)&-(a))
    using namespace std;
    typedef long long ll;
    template <class T>
    void read(T &x)
    {
        char c; bool op=0;
        while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
        x=c-'0';
        while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
        if(op) x=-x;
    }
    template <class T>
    void write(T x)
    {
        if(x<0) putchar('-'), x=-x;
        if(x>=10) write(x/10);
        putchar('0'+x%10);
    }
    
    const int maxn=1e5+5;
    
    int n;
    int a[maxn];
    ll k, sum[maxn];
    
    bool check(int val)
    {
        bool ok=false;
        for(int i=1; i<=n; i++)
        {
            int low=i;
            int high=lower_bound(a+1, a+1+n, a[i]+val)-a;
            ll area=1ll*low*a[low]-sum[low]+sum[n]-sum[high-1]-1ll*(n-high+1)*(a[low]+val);
            //printf("! val=%d, low=%d, high=%d, area=%I64d
    ", val, low, high, area);
            if(area<=k) ok=true;
        }
        if(ok) return ok;
        for(int i=1; i<=n; i++)
        {
            int low=lower_bound(a+1, a+1+n, a[i]-val)-a-1;  //注意这里要减去1
            int high=i;
            ll area=1ll*low*(a[high]-val)-sum[low]+sum[n]-sum[high-1]-1ll*(n-high+1)*a[high];
            //printf("! val=%d, low=%d, high=%d, area=%I64d
    ", val, low, high, area);
            if(area<=k) ok=true;
        }
        return ok;
    }
    
    int main()
    {
        IO_read;
        //fre;
        cin>>n>>k;
        for(int i=1; i<=n; i++) cin>>a[i];
        sort(a+1, a+1+n);
        for(int i=1; i<=n; i++) sum[i]=sum[i-1]+a[i];
        int l=0, r=a[n]-a[1];
        while(l<r)
        {
            int mid=l+r>>1;
            if(check(mid)) r=mid;
            else l=mid+1;
            //printf("! l=%d, r=%d, mid=%d
    ", l, r, mid);
        }
        cout<<l<<"
    ";
    }
  • 相关阅读:
    java虚拟机之垃圾回收机制
    java虚拟机之JVM体系结构
    java虚拟机之JVM生命周期
    删除链表中重复的结点
    (二十一)java多线程之Executors
    (十八)java多线程之Callable Future
    (十六)java多线程之优先队列PriorityBlockingQueue
    (十九)java多线程之ForkJoinPool
    (二十)java多线程之ScheduledThreadPoolExecutor
    (六)java多线程之ReadWriteLock
  • 原文地址:https://www.cnblogs.com/Yokel062/p/11748490.html
Copyright © 2011-2022 走看看