結果
問題 | No.2704 L to R Graph |
ユーザー | 👑 hos.lyric |
提出日時 | 2024-03-29 23:34:59 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 91 ms / 3,000 ms |
コード長 | 6,233 bytes |
コンパイル時間 | 1,458 ms |
コンパイル使用メモリ | 129,736 KB |
実行使用メモリ | 25,948 KB |
最終ジャッジ日時 | 2024-09-30 17:04:08 |
合計ジャッジ時間 | 4,594 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 71 ms
19,440 KB |
testcase_09 | AC | 69 ms
19,432 KB |
testcase_10 | AC | 69 ms
19,412 KB |
testcase_11 | AC | 68 ms
23,220 KB |
testcase_12 | AC | 67 ms
23,352 KB |
testcase_13 | AC | 69 ms
23,332 KB |
testcase_14 | AC | 69 ms
23,224 KB |
testcase_15 | AC | 69 ms
23,220 KB |
testcase_16 | AC | 68 ms
23,220 KB |
testcase_17 | AC | 67 ms
23,348 KB |
testcase_18 | AC | 71 ms
23,352 KB |
testcase_19 | AC | 71 ms
23,348 KB |
testcase_20 | AC | 73 ms
23,216 KB |
testcase_21 | AC | 91 ms
23,524 KB |
testcase_22 | AC | 83 ms
22,756 KB |
testcase_23 | AC | 84 ms
23,268 KB |
testcase_24 | AC | 81 ms
23,092 KB |
testcase_25 | AC | 85 ms
25,948 KB |
testcase_26 | AC | 80 ms
24,404 KB |
testcase_27 | AC | 82 ms
24,244 KB |
testcase_28 | AC | 78 ms
22,832 KB |
ソースコード
#include <cassert> #include <cmath> #include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <functional> #include <iostream> #include <limits> #include <map> #include <numeric> #include <queue> #include <random> #include <set> #include <sstream> #include <string> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> using namespace std; using Int = long long; template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; }; template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; } template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } #define COLOR(s) ("\x1b[" s "m") // element to erase must exist template <class T> struct MinPQue { priority_queue<T, vector<T>, greater<T>> que0, que1; int size() const { return que0.size() - que1.size(); } void push(const T &t) { que0.push(t); } void erase(const T &t) { que1.push(t); } void reduce() { for (; que0.size() && que1.size() && que0.top() == que1.top(); que0.pop(), que1.pop()) {} } const T &top() { reduce(); return que0.top(); } void pop() { reduce(); que0.pop(); } }; struct Functional { int n; vector<int> par; int cyclesLen; vector<vector<int>> cycles; // cycle id or -1 vector<int> on; // forest vector<vector<int>> graph; // root vector<int> rs; Functional() {} Functional(const vector<int> &par_) : par(par_) { n = par.size(); cycles.clear(); vector<int> vis(n, -1); for (int s = 0; s < n; ++s) { int u = s; for (; !~vis[u]; u = par[u]) { vis[u] = s; } if (vis[u] == s) { vector<int> cycle; for (int v = u; ; ) { cycle.push_back(v); if ((v = par[v]) == u) break; } cycles.push_back(cycle); } } cyclesLen = cycles.size(); on.assign(n, -1); for (int k = 0; k < cyclesLen; ++k) { for (const int u : cycles[k]) { on[u] = k; } } graph.assign(n, {}); for (int u = 0; u < n; ++u) if (!~on[u]) { graph[par[u]].push_back(u); } rs.assign(n, -1); zeit = 0; dis.assign(n, -1); fin.assign(n, -1); dep.assign(n, -1); for (int u = 0; u < n; ++u) if (~on[u]) { dep[u] = 0; dfs(u, u); } } void dfs(int u, int r) { dis[u] = zeit++; rs[u] = r; for (const int v : graph[u]) { dep[v] = dep[u] + 1; dfs(v, r); } fin[u] = zeit; } int zeit; vector<int> dis, fin, dep; }; constexpr int INF = 1001001001; int N, L, R; vector<int> P; int Q; vector<int> S, T; int main() { for (; ~scanf("%d%d%d", &N, &L, &R); ) { P.resize(N); for (int u = 0; u < N; ++u) { scanf("%d", &P[u]); --P[u]; } scanf("%d", &Q); S.resize(Q); T.resize(Q); for (int q = 0; q < Q; ++q) { scanf("%d%d", &S[q], &T[q]); --S[q]; --T[q]; } const Functional F(P); // cerr<<"cycles = "<<F.cycles<<endl; const int K = F.cyclesLen; vector<int> freq(K, 0); for (int u = 0; u < N; ++u) { ++freq[F.on[F.rs[u]]]; } vector<int> ns(K + 1), ms(K + 1); vector<vector<int>> cost(K + 1), costSuf(K + 1); for (int k = 0; k <= K; ++k) { int &n = ns[k]; int &m = ms[k]; if (k == K) { n = N; m = 1; } else { n = freq[k]; m = F.cycles[k].size(); } vector<vector<int>> addss(n + m + 1), remss(n + m + 1); for (Int x = 0; x <= n + m; ++x) { // [0, n) { Int l = L * x, r = R * x; chmin<Int>(r, n - 1); if (l <= r) { addss[l].push_back(x); remss[r + 1].push_back(x); } } // [n, n + m) { Int l = L * x, r = R * x; chmax<Int>(l, n); if (l <= r) { if (r - l >= m - 1) { addss[n].push_back(x); remss[n + m].push_back(x); } else { const Int a = (l - n) % m; const Int b = (a + (r - l)) % m; if (a <= b) { addss[n + a].push_back(x); remss[n + b + 1].push_back(x); } else { addss[n + a].push_back(x); remss[n + m].push_back(x); addss[n].push_back(x); remss[n + b + 1].push_back(x); } } } } } MinPQue<int> que; que.push(INF); cost[k].assign(n + m, INF); for (int d = 0; d < n + m; ++d) { for (const int x : addss[d]) que.push(x); for (const int x : remss[d]) que.erase(x); cost[k][d] = que.top(); } costSuf[k] = cost[k]; for (int d = n; --d >= 0; ) { chmin(costSuf[k][d], costSuf[k][d + m]); } } /* cerr<<"ns = "<<ns<<endl; cerr<<"ms = "<<ms<<endl; cerr<<"cost = "<<cost<<endl; //*/ vector<int> ls(N, -1); for (int k = 0; k < K; ++k) { for (int l = 0; l < (int)F.cycles[k].size(); ++l) { ls[F.cycles[k][l]] = l; } } for (int q = 0; q < Q; ++q) { const int s = S[q], t = T[q]; const int k = F.on[t]; int ans = INF; if (~k) { if (F.on[F.rs[s]] == k) { int d = ls[t] - ls[F.rs[s]]; if (d < 0) d += ms[k]; d += F.dep[s]; // cerr<<"s = "<<s<<", t = "<<t<<", k = "<<k<<", d = "<<d<<endl; ans = costSuf[k][d]; } } else { if (F.dis[t] <= F.dis[s] && F.dis[s] < F.fin[t]) { ans = cost[K][F.dep[s] - F.dep[t]]; } } printf("%d\n", (ans < INF) ? ans : -1); } } return 0; }