可持久化并查集 10pts 求助

P4768 [NOI2018] 归程

```cpp #include <bits/stdc++.h> using namespace std; namespace liuzimingc { #define int long long #define pii pair<int, int> #define endl '\n' const int N = 8e5 + 5, INF = 1e18; int T, n, m, a[N], lastans, pos[N]; // >= i 的最后一个位置,最后后缀跑一下 int dis[N]; bool vis[N]; priority_queue<pii> q; vector<pii> e[N]; vector<int> lsh; struct edge { int u, v, w; } edge[N]; struct persistent_segment_tree { int root[N], tot, a[N]; struct tree { int l, r, v; } t[N << 3]; void build(int &p, int l, int r) { p = ++tot; t[p].l = l, t[p].r = r; if (l == r) { t[p].v = a[l]; return; } int mid = l + r >> 1; build(t[p].l, l, mid); build(t[p].r, mid + 1, r); } void update(int &p, int pre, int l, int r, int x, int v) { p = ++tot; t[p] = t[pre]; if (l == r) { t[p].v = v; return; } int mid = l + r >> 1; if (x <= mid) update(t[p].l, t[p].l, l, mid, x, v); else update(t[p].r, t[p].r, mid + 1, r, x, v); } int ask(int p, int l, int r, int x) { if (l == r) return t[p].v; int mid = l + r >> 1; if (x <= mid) return ask(t[p].l, l, mid, x); else return ask(t[p].r, mid + 1, r, x); } } fa, siz, d; int find(int x, int p) { int f = fa.ask(fa.root[p], 1, n, x); return f == x ? x : find(f, p); } void merge(int x, int y, int p) { x = find(x, p), y = find(y, p); if (x == y) return; int sizx = siz.ask(siz.root[p], 1, n, x), sizy = siz.ask(siz.root[p], 1, n, y); int dx = d.ask(d.root[p], 1, n, x), dy = d.ask(d.root[p], 1, n, y); if (sizx > sizy) swap(x, y); fa.update(fa.root[p], fa.root[p], 1, n, x, y); siz.update(siz.root[p], siz.root[p], 1, n, y, sizx + sizy); d.update(d.root[p], d.root[p], 1, n, y, min(dx, dy)); } void dijkstra(int s) { for (int i = 1; i <= n; i++) dis[i] = INF, vis[i] = false; q.push(make_pair(0, s)); dis[s] = 0; while (q.size()) { int u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = true; for (const auto &i : e[u]) { int v = i.first, w = i.second; if (dis[u] + w < dis[v]) { dis[v] = dis[u] + w; q.push(make_pair(-dis[v], v)); } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> T; while (T--) { cin >> n >> m; for (int i = 1; i <= n; i++) e[i].clear(); lsh.clear(); for (int i = 1; i <= m; i++) { int u, v, w, a; cin >> u >> v >> w >> a; edge[i].u = u, edge[i].v = v, edge[i].w = a; lsh.push_back(a); e[u].push_back(make_pair(v, w)); e[v].push_back(make_pair(u, w)); } lsh.push_back(-1); sort(lsh.begin(), lsh.end()); lsh.resize(unique(lsh.begin(), lsh.end()) - lsh.begin()); dijkstra(1); sort(edge + 1, edge + 1 + m, [](auto a, auto b){ return a.w > b.w; }); fa.tot = siz.tot = d.tot = 0; for (int i = 1; i <= n; i++) fa.a[i] = i, siz.a[i] = 1, d.a[i] = dis[i]; fa.build(fa.root[0], 1, n); siz.build(siz.root[0], 1, n); d.build(d.root[0], 1, n); for (int i = 1; i <= m; i++) { fa.root[i] = fa.root[i - 1]; siz.root[i] = siz.root[i - 1]; d.root[i] = d.root[i - 1]; merge(edge[i].u, edge[i].v, i); edge[i].w = lower_bound(lsh.begin(), lsh.end(), edge[i].w) - lsh.begin(); pos[edge[i].w] = i; } pos[lsh.size()] = 0; for (int i = lsh.size() - 1; i; i--) pos[i] = max(pos[i], pos[i + 1]); int q, k, s; cin >> q >> k >> s; lastans = 0; for (int case_id = 1; case_id <= q; case_id++) { int v, p; cin >> v >> p; v = (v + k * lastans - 1) % n + 1; p = (p + k * lastans) % (s + 1); if (lsh.back() <= p) { // cerr << case_id << endl; cout << (lastans = dis[v]) << endl; continue; } int x = upper_bound(lsh.begin(), lsh.end(), p) - lsh.begin(); x = pos[x]; int f = fa.ask(fa.root[x], 1, n, v); cout << (lastans = d.ask(d.root[x], 1, n, f)) << endl; } } return 0; } #undef int } int main() { liuzimingc::main(); return 0; } ```
by liuzimingc @ 2024-08-15 15:04:45


|