結果

問題 No.2242 Cities and Teleporters
ユーザー hitonanodehitonanode
提出日時 2023-03-11 00:05:34
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 477 ms / 3,000 ms
コード長 3,048 bytes
コンパイル時間 1,336 ms
コンパイル使用メモリ 110,576 KB
実行使用メモリ 39,260 KB
最終ジャッジ日時 2023-10-18 09:20:52
合計ジャッジ時間 11,936 ms
ジャッジサーバーID
(参考情報)
judge13 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,348 KB
testcase_01 AC 2 ms
4,348 KB
testcase_02 AC 2 ms
4,348 KB
testcase_03 AC 2 ms
4,348 KB
testcase_04 AC 1 ms
4,348 KB
testcase_05 AC 349 ms
22,100 KB
testcase_06 AC 319 ms
22,100 KB
testcase_07 AC 355 ms
22,100 KB
testcase_08 AC 477 ms
22,100 KB
testcase_09 AC 317 ms
22,100 KB
testcase_10 AC 240 ms
39,260 KB
testcase_11 AC 290 ms
39,260 KB
testcase_12 AC 288 ms
39,260 KB
testcase_13 AC 311 ms
39,260 KB
testcase_14 AC 365 ms
39,260 KB
testcase_15 AC 306 ms
39,260 KB
testcase_16 AC 359 ms
39,260 KB
testcase_17 AC 456 ms
39,260 KB
testcase_18 AC 314 ms
38,688 KB
testcase_19 AC 466 ms
38,672 KB
testcase_20 AC 297 ms
37,536 KB
testcase_21 AC 286 ms
37,816 KB
testcase_22 AC 449 ms
37,536 KB
testcase_23 AC 463 ms
39,260 KB
testcase_24 AC 448 ms
39,260 KB
testcase_25 AC 454 ms
39,260 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define REP(i, n) FOR(i,0,n)
template <typename T> bool chmax(T &m, const T q) { return m < q ? (m = q, true) : false; }
template <class T> std::vector<T> sort_unique(std::vector<T> vec) { sort(vec.begin(), vec.end()), vec.erase(unique(vec.begin(), vec.end()), vec.end()); return vec; }
template <class T> int arglb(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::lower_bound(v.begin(), v.end(), x)); }
template <class IStream, class T> IStream &operator>>(IStream &is, std::vector<T> &vec) { for (auto &v : vec) is >> v; return is; }

// Binary lifting / `Doubling`
// Complexity: O(NlogN) precalculation / O(logN) per query
// <https://atcoder.jp/contests/arc060/submissions/7039451>
struct BinaryLifting {
    int N, INVALID, lgD;
    std::vector<std::vector<int>> mat;
    BinaryLifting() : N(0), lgD(0) {}
    BinaryLifting(const std::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, std::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
    }
};


int main() {
    cin.tie(nullptr), ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<int> H(N), T(N);
    cin >> H >> T;
    auto z = H;
    z.insert(z.end(), ALL(T));
    z = sort_unique(z);
    for (auto &x : H) x = arglb(z, x);
    for (auto &x : T) x = arglb(z, x);

    const int sz = z.size();
    vector<int> to(sz);
    REP(i, sz) to.at(i) = i;
    REP(i, N) chmax(to.at(H.at(i)), T.at(i));
    
    FOR(i, 1, sz) chmax(to.at(i), to.at(i - 1));

    BinaryLifting bl(to);

    int Q;
    cin >> Q;
    while (Q--) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        int h1 = T.at(a);
        int hgoal = H.at(b);
        auto ret = bl.distance(h1, hgoal);
        if (ret >= 0) {
            ++ret;
        }
        cout << ret << '\n';
    }
}
0