結果
| 問題 |
No.2242 Cities and Teleporters
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-08-27 18:19:44 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 465 ms / 3,000 ms |
| コード長 | 3,157 bytes |
| コンパイル時間 | 2,486 ms |
| コンパイル使用メモリ | 206,284 KB |
| 最終ジャッジ日時 | 2025-02-16 15:15:52 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 26 |
ソースコード
#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;
}