1 solutions

  • 0
    @ 2025-6-4 12:55:26

    二分答案
    k k 进行二分查找。设当前二分值为 mid mid ,检查是否存在一个 x x 满足所有区间包含 x x

    对于每个区间,左端点为 Li=aimidbi L_i = a_i - mid \cdot b_i ,右端点为 Ri=ai+midbi R_i = a_i + mid \cdot b_i

    所有区间有公共交点的充要条件是:左端点的最大值 max(Li) \max(L_i) \leq 右端点的最小值 min(Ri) \min(R_i)

    计算 max_L=max{aimidbi} \max\_L = \max\{a_i - mid \cdot b_i\} min_R=min{ai+midbi} \min\_R = \min\{a_i + mid \cdot b_i\} ,若 max_Lmin_R \max\_L \leq \min\_R ,则 k=mid k = mid 可行,否则不可行。

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define fr(i, a, b) for (int i = (a); i <= (b); i++)
    const int inf = 0x3f3f3f3f;
    const int N = 1e6 + 10;
    
    void slove() {
        int n;
        cin >> n;
        vector<int> a(n + 1), b(n + 1);
        fr(i, 1, n) cin >> a[i];
        fr(i, 1, n) cin >> b[i];
        
        auto check = [&](int mid) -> bool {
            int minr = 1e18, maxl = -1e18;
            fr(i, 1, n) {
                minr = min(minr, a[i] + b[i] * mid);
                maxl = max(maxl, a[i] - b[i] * mid);
            }
            return minr >= maxl;
        };
        
        int l = 0, r = 1e18;
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (check(mid)) r = mid;
            else l = mid + 1;
        }
        cout << l << endl;
    }
    
    signed main() {
        ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        int tcase = 1;
        // cin >> tcase;
        while (tcase--) slove();
        return 0;
    }
    
    • 1

    Information

    ID
    1495
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    9
    Tags
    (None)
    # Submissions
    68
    Accepted
    6
    Uploaded By