1 条题解

  • 0
    @ 2026-5-5 2:27:39

    发现要求是这 kk 个数和在 [A,2A][A,2A] 之间,这个 2A2A 肯定有说法。

    分类讨论有没有选择 A\geq A 的数。如果选择了,一定是仅选择一个 A\geq A 中最小的数,这时已经满足 A\geq A 了,剩下的肯定是要取前 k1k-1 小。

    如果没有选择,那么先默认选择最小的 kk 个数,如果和 <A<A,就不断把最小的数换成 <A<A 的数中最大的数,这样每次的变化量都小于 AA,不会突然超过 2A2A 的上界限制。

    要先找到第一个 A\geq A 的数的下标 ii,还要知道下标在 [1,k][1,k][ik,i1][i-k,i-1] 中的数的值,总询问次数 logn+2k\log n+2k

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define ll long long
    using namespace std;
    const int MAXN=1e5+10;ll a[MAXN],s;
    extern "C" long long skim (int i);
    extern "C" void answer (std::vector<int> v);
    extern "C" void impossible ();
    extern "C" void solve(int n,int k,ll A,int S)
    {
        vector <int> ans;
        for(int i=1;i<=k;++i)
            s+=(a[i]=skim(i)),ans.push_back(i);
        if(s>=A&&s<=2*A) answer(ans);
        if(a[k]>=A) impossible();
        int l=k+1,r=n+1;while(l<r)
        {
            int mid=(l+r)>>1;
            skim(mid)>A?r=mid:l=mid+1;
        }
        if(l<=n&&s-a[k]+skim(l)<=2*A)
            ans.pop_back(),ans.push_back(l),answer(ans);
        for(int i=l-1;i>=max(l-k,k+1);--i)
        {
            s=s-a[l-i]+skim(i);
            ans.erase(ans.begin()),ans.push_back(i);
            if(s>=A) answer(ans);
        }
        impossible();
    }
    
    • 1

    「BalticOI 2021 Day1」A Difficult Choice

    信息

    ID
    10565
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者