結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
m_tsubasa
|
| 提出日時 | 2020-06-04 10:38:39 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,320 bytes |
| コンパイル時間 | 3,512 ms |
| コンパイル使用メモリ | 225,592 KB |
| 最終ジャッジ日時 | 2025-01-10 21:08:57 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 7 WA * 11 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
// 0-indexed
template <class T>
struct SegmentTree {
// a,b,c: T, e:T(unit)
// abc = (ab)c = a(bc)
// ae = ea = a
typedef function<T(T, T)> F;
int n;
F f;
T unit;
vector<T> dat;
SegmentTree(){};
SegmentTree(int newn, F f, T t) : f(f), unit(t) { init(newn); }
SegmentTree(const vector<T> &v, F f, T t) : f(f), unit(t) {
int _n = v.size();
init(v.size());
for (int i = 0; i < _n; ++i) dat[n + i] = v[i];
for (int i = n - 1; i; --i) dat[i] = f(dat[i << 1], dat[(i << 1) | 1]);
}
void init(int newn) {
n = 1;
while (n < newn) n <<= 1;
dat.assign(n << 1, unit);
}
// "go up" process
void update(int k, T newdata) {
dat[k += n] = newdata;
while (k >>= 1) {
dat[k] = f(dat[(k << 1) | 0], dat[(k << 1) | 1]);
}
}
// [a,b)
T query(int a, int b) {
T vl = unit, vr = unit;
for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
if (l & 1) vl = f(vl, dat[l++]);
if (r & 1) vr = f(dat[--r], vr);
}
return f(vl, vr);
}
};
struct HeavyLightDecomposition {
int root;
vector<vector<int>> g;
vector<int> sz, par, dep, in, out, head;
HeavyLightDecomposition(int n = 1, int _root = 0)
: root(_root), g(n), sz(n), par(n), dep(n), in(n), out(n), head(n) {}
HeavyLightDecomposition(const vector<vector<int>> &_g, const int _root = 0)
: root(_root),
g(_g),
sz(_g.size()),
par(_g.size()),
dep(_g.size()),
in(_g.size()),
out(_g.size()),
head(_g.size()) {
build();
}
void add(int a, int b) {
g[a].push_back(b);
g[b].push_back(a);
}
void build() {
dfs_sz(root, -1, 0);
int t = 0;
dfs_hld(root, -1, t);
}
void dfs_sz(int now, int bf, int d) {
dep[now] = d;
par[now] = bf;
sz[now] = 1;
if (g[now].size() && g[now][0] == bf) swap(g[now][0], g[now].back());
for (auto &to : g[now]) {
if (to == bf) continue;
dfs_sz(to, now, d + 1);
sz[now] += sz[to];
if (sz[g[now][0]] < sz[to]) swap(g[now][0], to);
}
}
void dfs_hld(int now, int bf, int &t) {
in[now] = t++;
for (auto &to : g[now]) {
if (to == bf) continue;
head[to] = (g[now][0] == to ? head[now] : to);
dfs_hld(to, now, t);
}
out[now] = t;
}
int lca(int x, int y) {
for (;; y = par[head[y]]) {
if (in[x] > in[y]) swap(x, y);
if (head[x] == head[y]) return x;
}
}
int chil(int x, int y) { return dep[x] < dep[y] ? y : x; }
//[l,r)
template <typename F>
void for_each(int x, int y, const F &f) {
for (;; y = par[head[y]]) {
if (in[x] > in[y]) swap(x, y);
f(max(in[head[y]], in[x]), in[y] + 1);
if (head[x] == head[y]) return;
}
}
//[l,r)
template <typename F>
void for_eachedge(int x, int y, const F &f) {
while (1) {
if (in[x] > in[y]) swap(x, y);
if (head[x] != head[y]) {
f(in[head[y]], in[y] + 1);
y = par[head[y]];
} else {
if (x != y) f(in[x] + 1, in[y] + 1);
break;
}
}
}
template <typename T, typename F>
void update(int node, T x, const F &f) {
f(in[node], x);
f(out[node], -x);
// laze pattern
// f(in[node], out[node], x);
}
};
// TwoEdgeConnectedComponents + LowLink
struct TwoEdgeConnectedComponents {
int n;
vector<vector<int>> g;
vector<int> ord, low, articulation, id;
vector<bool> used;
using P = pair<int, int>;
vector<P> bridge;
TwoEdgeConnectedComponents(int _n = 1) : n(_n), g(n) {}
TwoEdgeConnectedComponents(vector<vector<int>> &_g) : n(_g.size()), g(_g) {
lowlinkbuild();
}
bool add(int from, int to) {
g[from].push_back(to);
g[to].push_back(from);
return 1;
}
void lowlinkbuild() {
ord.assign(n, -1);
low.assign(n, -1);
int k = 0;
for (int i = 0; i < n; ++i)
if (ord[i] < 0) lowlinkdfs(i, -1, k);
}
void lowlinkdfs(int now, int par, int &k) {
ord[now] = low[now] = k++;
bool ch = 0; // articulation
int cnt = 0;
for (auto &to : g[now])
if (ord[to] < 0) {
++cnt;
lowlinkdfs(to, now, k);
low[now] = min(low[now], low[to]);
ch |= ~par && low[to] >= ord[now]; // articulation
if (ord[now] < low[to])
bridge.emplace_back(min(now, to), max(now, to)); // bridge
} else if (to != par)
low[now] = min(low[now], ord[to]);
ch |= par == -1 && cnt > 1; // articulation
if (ch) articulation.push_back(now); // articulation
}
vector<vector<int>> build() {
id.assign(n, -1);
int k = 0;
for (int i = 0; i < n; ++i)
if (id[i] < 0) dfs(i, -1, k);
vector<vector<int>> res(k);
for (auto &e : bridge) {
int x = id[e.first], y = id[e.second];
res[x].push_back(y);
res[y].push_back(x);
}
return res;
}
void dfs(int now, int par, int &k) {
if (~par && ord[par] >= low[now])
id[now] = id[par];
else
id[now] = k++;
for (auto &to : g[now])
if (id[to] < 0) dfs(to, now, k);
}
inline int operator[](const int &k) { return (id.at(k)); }
};
using P = pair<long long, long long>;
long long n, m, q;
TwoEdgeConnectedComponents tecc;
SegmentTree<P> seg;
HeavyLightDecomposition hld;
vector<vector<int>> g;
vector<priority_queue<long long>> lst;
int main() {
cin >> n >> m >> q;
g.resize(n);
for (int i = 0; i < m; ++i) {
int a, b;
cin >> a >> b;
g[--a].push_back(--b);
g[b].push_back(a);
}
tecc = TwoEdgeConnectedComponents(g);
hld = HeavyLightDecomposition(tecc.build());
lst.resize(n);
auto f = [](P l, P r) { return max(l, r); };
seg = SegmentTree<P>(n, f, P(-1, -1));
for (int i = 0; i < q; ++i) {
int a, b, c;
cin >> a >> b >> c;
if (a == 1) {
int x = tecc[--b];
lst[x].push(c);
seg.update(x, P(lst[x].top(), x));
} else {
int x = tecc[--b], y = tecc[--c];
P res(-1, -1);
auto func = [&](int l, int r) { res = max(res, seg.query(l, r)); };
hld.for_each(x, y, func);
cout << res.first << endl;
if (res.first >= 0) {
x = res.second;
lst[x].pop();
long long num = -1;
if (lst[x].size()) num = lst[x].top();
seg.update(x, P(num, x));
}
}
}
return 0;
}
m_tsubasa