結果
| 問題 |
No.2296 Union Path Query (Hard)
|
| コンテスト | |
| ユーザー |
Kude
|
| 提出日時 | 2024-04-21 02:37:26 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 373 ms / 7,000 ms |
| コード長 | 3,036 bytes |
| コンパイル時間 | 3,580 ms |
| コンパイル使用メモリ | 285,708 KB |
| 実行使用メモリ | 28,288 KB |
| 最終ジャッジ日時 | 2024-10-13 01:06:18 |
| 合計ジャッジ時間 | 20,317 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 45 |
ソースコード
#include<bits/stdc++.h>
namespace {
#pragma GCC diagnostic ignored "-Wunused-function"
#include<atcoder/all>
#pragma GCC diagnostic warning "-Wunused-function"
using namespace std;
using namespace atcoder;
#define rep(i,n) for(int i = 0; i < (int)(n); i++)
#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; }
template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; }
using ll = long long;
using P = pair<int,int>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
struct Node {
int depth, parent, jump;
};
struct Diam {
int u, v;
ll d;
friend bool operator<(const Diam& lhs, const Diam& rhs) {
return lhs.d < rhs.d;
}
};
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, x, q;
cin >> n >> x >> q;
vector<vector<pair<int, ll>>> g(n);
VL ws(n);
vector<Node> nodes(n);
rep(i, n) nodes[i] = {0, i, i};
vector<Diam> diam(n);
rep(i, n) diam[i] = {i, i, 0};
dsu uf(n);
auto dist = [&](int u, int v) {
ll res = ws[u] + ws[v];
if (nodes[u].depth < nodes[v].depth) swap(u, v);
while (nodes[u].depth != nodes[v].depth) {
int uj = nodes[u].jump;
if (nodes[uj].depth >= nodes[v].depth) u = uj;
else u = nodes[u].parent;
}
while (u != v) {
int uj = nodes[u].jump, vj = nodes[v].jump;
if (uj != vj) u = uj, v = vj;
else u = nodes[u].parent, v = nodes[v].parent;
}
res -= 2 * ws[u];
return res;
};
while (q--) {
int type;
cin >> type;
if (type == 1) {
int v, w;
cin >> v >> w;
int u = x;
if (uf.size(u) > uf.size(v)) swap(u, v);
int lu = uf.leader(u), lv = uf.leader(v);
int l = uf.merge(u, v);
auto dfs = [&](auto&& self, int u, int p, ll w_now) -> void {
int pj = nodes[p].jump, pjj = nodes[pj].jump;
nodes[u] = {
nodes[p].depth + 1,
p,
nodes[p].depth + nodes[pjj].depth == 2 * nodes[pj].depth ? pjj : p
};
ws[u] = w_now;
for (auto [vi, wi] : g[u]) if (vi != p) self(self, vi, u, w_now + wi);
};
dfs(dfs, u, v, w + ws[v]);
g[u].emplace_back(v, w);
g[v].emplace_back(u, w);
Diam d = max(diam[lu], diam[lv]);
for (int u : {diam[lu].u, diam[lu].v}) {
for (int v : {diam[lv].u, diam[lv].v}) {
chmax(d, Diam{u, v, dist(u, v)});
}
}
diam[l] = d;
} else if (type == 2) {
int u, v;
cin >> u >> v;
if (!uf.same(u, v)) {
cout << -1 << '\n';
} else {
ll ans = dist(u, v);
cout << ans << '\n';
x = (x + ans) % n;
}
} else if (type == 3) {
int v;
cin >> v;
cout << diam[uf.leader(v)].d << '\n';
} else {
int value;
cin >> value;
x = (x + value) % n;
}
}
}
Kude