結果

問題 No.2242 Cities and Teleporters
ユーザー intfansintfans
提出日時 2023-08-27 18:19:44
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 465 ms / 3,000 ms
コード長 3,157 bytes
コンパイル時間 2,507 ms
コンパイル使用メモリ 212,196 KB
実行使用メモリ 40,868 KB
最終ジャッジ日時 2023-08-27 18:20:00
合計ジャッジ時間 15,585 ms
ジャッジサーバーID
(参考情報)
judge12 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 AC 2 ms
4,384 KB
testcase_03 AC 1 ms
4,384 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 318 ms
23,476 KB
testcase_06 AC 282 ms
23,468 KB
testcase_07 AC 316 ms
23,520 KB
testcase_08 AC 415 ms
23,464 KB
testcase_09 AC 290 ms
23,524 KB
testcase_10 AC 225 ms
40,708 KB
testcase_11 AC 276 ms
40,572 KB
testcase_12 AC 267 ms
40,868 KB
testcase_13 AC 293 ms
40,556 KB
testcase_14 AC 338 ms
40,692 KB
testcase_15 AC 296 ms
40,676 KB
testcase_16 AC 339 ms
40,696 KB
testcase_17 AC 416 ms
40,572 KB
testcase_18 AC 294 ms
40,048 KB
testcase_19 AC 431 ms
39,972 KB
testcase_20 AC 317 ms
38,844 KB
testcase_21 AC 282 ms
39,248 KB
testcase_22 AC 415 ms
38,836 KB
testcase_23 AC 434 ms
40,540 KB
testcase_24 AC 465 ms
40,696 KB
testcase_25 AC 436 ms
40,660 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

// https://yukicoder.me/problems/no/2242

/*
n个城市,高度分别为h[1],..h[n]. 另给一个长度为n的数组t,从城市i出发,可以到达高度不超过t[i]的所有其他城市,
有q次询问,每次询问给出x,y,求从x到y的最少边数,如果无法到达y,输出-1.
+ 2 <= n <= 2e5
+ 1 <= q <= 2e5
+ 1 <= h[i], t[i] <= 1e9
+ 1 <= a[i], b[i] <= n
+ a[i] != b[i]
*/

using ll = long long;

// 预处理 O(NlogN);查询:O(logN)
struct BiLifting {
    int N, INVALID, lgD;
    vector<vector<int>> mat;
    BiLifting() : N(0), lgD(0) {}
    BiLifting(const vector<int> &vec_nxt, int INVALID = -1, int lgd = 0)
        : N(vec_nxt.size()), INVALID(INVALID), lgD(lgd) {
        while ((1LL << lgD) < N) lgD++;
        mat.assign(lgD, vector<int>(N, INVALID));
        mat[0] = vec_nxt;
        for (int i = 0; i < N; i++)
            if (mat[0][i] < 0 or mat[0][i] >= N) mat[0][i] = INVALID;
        for (int d = 0; d < lgD - 1; d++) {
            for (int i = 0; i < N; i++)
                if (mat[d][i] != INVALID) mat[d + 1][i] = mat[d][mat[d][i]];
        }
    }
    int kth_next(int now, long long k) {
        if (k >= (1LL << lgD)) exit(8);
        for (int d = 0; k and now != INVALID; d++, k >>= 1)
            if (k & 1) now = mat[d][now];
        return now;
    }

    // Distance from l to [r, infty)
    // Requirement: mat[0][i] > i for all i (monotone increasing)
    int distance(int l, int r) {
        if (l >= r) return 0;
        int ret = 0;
        for (int d = lgD - 1; d >= 0; d--) {
            if (mat[d][l] < r and mat[d][l] != INVALID) ret += 1 << d, l = mat[d][l];
        }
        if (mat[0][l] == INVALID or mat[0][l] >= r)
            return ret + 1;
        else
            return -1; // Unable to reach
    }
};

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};


int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n;
    cin >> n;
    vector<int> h(n), t(n);
    for (int &x : h)
        cin >> x;
    for (int &x : t)
        cin >> x;

    auto z = h;
    z.insert(z.end(), t.begin(), t.end());
    Discrete<int> v(z);

    for (auto &x : h) 
        x = v(x);
    for (auto &x : t) 
        x = v(x);
    int m = v.size();
    vector<int> g(m);
    iota(g.begin(), g.end(), 0);
    for (int i = 0; i < n; ++i) 
        g[h[i]] = max(g[h[i]], t[i]);
    for (int i = 1; i < m; ++i)
        g[i] = max(g[i], g[i - 1]);

    BiLifting bl(g);
    int q;
    cin >> q;
    for (int i = 0; i < q; ++i) {
        int x, y;
        cin >> x >> y;
        x--, y--;
        int l = t[x], r = h[y];
        auto c = bl.distance(l, r);
        if (c >= 0) c++;
        cout << c << '\n';
    }
   
    return 0;
}
0