题解 CF1840D【Wooden Toy Festival】

不妨设 a 单调递增(无重复),显然如果 n3 答案就是 0

显然答案 k 具有可二分性。也就是说,当 k<k0 时一定不存在合法的 x,y,z,当 kk0 时一定存在,k0 就是答案。

因此二分答案,只需要验证答案 k 是否存在合法的 x,y,z

为了覆盖到 a1,且 x 尽量往大取(这样可以覆盖更多的 ai),我们令 x=a1+k。接下来一段区间的 ai 会被 [xk,x+k] 覆盖,我们跳过这段区间,找到下一个未被覆盖的 ai。类似于刚刚的思路,我们令 y=ai+k,再找到下一个未被覆盖的 aj,令 z=aj+k。如果此时所有 ai 都被覆盖了,那么就合法,否则不合法。

时间复杂度 O(nlogw),其中 w 为值域。

//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x,y,z) for(ll x=(y);x<=(z);x++)
#define per(x,y,z) for(ll x=(y);x>=(z);x--)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;

mt19937 rnd(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
ll randint(ll L, ll R) {
    uniform_int_distribution<ll> dist(L, R);
    return dist(rnd);
}

template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}

const ll N = 2e5+5, inf = numeric_limits<ll>::max();

ll T, n, a[N];

bool check(ll M) {
    ll x = a[1] + M, y = inf, z = inf;
    rep(i, 1, n) {
        if(abs(a[i] - x) <= M);
        else if(y == inf) y = a[i] + M;
        else if(abs(a[i] - y) <= M);
        else if(z == inf) z = a[i] + M;
        else if(abs(a[i] - z) <= M);
        else return false;
    }
    return true;
}

int main() {
    for(scanf("%lld", &T); T; T--) {
        scanf("%lld", &n);
        rep(i, 1, n) scanf("%lld", &a[i]);
        sort(a+1, a+1+n);
        n = unique(a+1, a+1+n) - a - 1;
        if(n <= 3) {puts("0"); continue;}
        ll L = 0, R = a[n] - a[1] + 1;
        while(L < R) {
            ll M = (L + R) >> 1;
            if(check(M)) R = M;
            else L = M + 1;
        }
        printf("%lld\n", L);
    }
    return 0;
}
posted @   rui_er  阅读(81)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示