結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2017-06-14 12:53:40 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 7,043 bytes |
| コンパイル時間 | 2,628 ms |
| コンパイル使用メモリ | 213,968 KB |
| 実行使用メモリ | 55,452 KB |
| 最終ジャッジ日時 | 2024-09-24 20:09:04 |
| 合計ジャッジ時間 | 10,116 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 WA * 1 |
| other | AC * 2 WA * 16 |
ソースコード
#include "bits/stdc++.h"
using namespace std;
#define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i))
#define rep(i,j) FOR(i,0,j)
#define each(x,y) for(auto &(x):(y))
#define mp make_pair
#define mt make_tuple
#define all(x) (x).begin(),(x).end()
#define debug(x) cout<<#x<<": "<<(x)<<endl
#define smax(x,y) (x)=max((x),(y))
#define smin(x,y) (x)=min((x),(y))
#define MEM(x,y) memset((x),(y),sizeof (x))
#define sz(x) (int)(x).size()
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
class TwoEdgeCC {
public:
TwoEdgeCC(vector<vector<int> > &G)
:V((int)G.size()), now(0), disc(V), low(V)
{
for (int i = 0; i < V; ++i) {
if (!disc[i]) {
dfs(G, i, -1);
}
}
if (stk.size()) {
tecc.push_back(vector<int>());
do {
tecc.back().push_back(stk.top());
stk.pop();
} while (stk.size());
}
}
vector<pair<int,int> > getBridges() {
return move(bridges);
}
vector<vector<int>> get() {
return move(tecc);
}
private:
int V, now;
vector<int> disc, low;
vector<pair<int,int> > bridges;
stack<int> stk;
vector<vector<int>> tecc;
void dfs(const vector<vector<int> > &G, int u, int parent) {
disc[u] = ++now;
low[u] = now;
stk.push(u);
for (int i = 0; i < (int)G[u].size(); ++i) {
int v = G[u][i];
if (!disc[v]) {
dfs(G, v, u);
low[u] = min(low[u], low[v]);
if (disc[u] < low[v]) {
int x = u, y = v;
if (x > y)swap(x, y);
bridges.emplace_back(x, y);
int w;
tecc.push_back(vector<int>());
do {
w = stk.top();
tecc.back().push_back(w);
stk.pop();
} while (w != v);
}
} else if (v != parent) {
low[u] = min(low[u], disc[v]);
}
}
}
};
class HLDecomposition {
int cur = 0;
void bfs(const vector<vector<int> > &G) {
queue<tuple<int, int, int> > que;
vector<int> order;
que.push(make_tuple(0, -1, 0));
while (!que.empty()) {
int u, pre, d;
tie(u, pre, d) = que.front();
que.pop();
parent[u] = pre;
depth[u] = d;
order.push_back(u);
for (int v : G[u])if (v != pre) {
que.push(make_tuple(v, u, d + 1));
}
}
reverse(order.begin(), order.end());
for (int u : order) {
sub[u] = 1;
for (int v : G[u])if (v != parent[u])sub[u] += sub[v];
}
}
void dfs_stk(const vector<vector<int> > & G) {
stack<pair<int, int> > stk;
stk.push(make_pair(0, 0));
while (!stk.empty()) {
int u, h, pre;
tie(u, h) = stk.top();
stk.pop();
head[u] = h;
id[u] = cur++;
pre = parent[u];
int heavy = -1, maxi = 0;
for (int v : G[u]) {
if (v != pre && maxi < sub[v]) {
maxi = sub[v];
heavy = v;
}
}
for (int v : G[u]) {
if (v != pre&&v != heavy) {
stk.push(make_pair(v, v));
}
}
if (heavy != -1)stk.push(make_pair(heavy, h));
}
}
public:
vector<int> parent, depth, sub, id, head;
HLDecomposition(const vector<vector<int> > &G) {
parent = depth = sub = id = head = vector<int>(G.size());
bfs(G);
dfs_stk(G);
}
/*
パス(u, v)を半開区間の集合に変換する。
O(log(|V|))
*/
vector<pair<int, int> > goUpToLCA(int u, int v) {
vector<pair<int, int> > res;
while (true) {
if (head[u] == head[v]) {
if (depth[u] > depth[v])swap(u, v);
res.emplace_back(id[u], id[v] + 1);
break;
} else {
if (depth[head[u]] > depth[head[v]])swap(u, v);
res.emplace_back(id[head[v]], id[v] + 1);
v = parent[head[v]];
}
}
return res;
}
};
template<class Val, class Cmp>
class DynamicRMQ {
int n;
Val init;
vector<Val> dat;
Cmp cmp;
inline Val query(int a, int b, int k, int l, int r) {
if (r <= a || b <= l) return init;
if (a <= l&&r <= b) return dat[k];
else {
Val vl, vr;
vl = query(a, b, k << 1, l, (l + r) >> 1);
vr = query(a, b, (k << 1) | 1, (l + r) >> 1, r);
return cmp(vl, vr) ? vl : vr;
}
}
public:
DynamicRMQ() {}
DynamicRMQ(int n_, Val init_) :n(1), init(init_) {
for (; n<n_; n <<= 1);
dat = vector<Val>(n << 1, init);
}
void update(int k, Val a) {
k += n;
dat[k] = a;
while (k > 1) {
k >>= 1;
dat[k] = cmp(dat[k << 1], dat[(k << 1) | 1]) ? dat[k << 1] : dat[(k << 1) | 1];
}
}
Val query(int a, int b) {
return query(a, b, 1, 0, n);
}
};
typedef DynamicRMQ<long long, less<long long> > RMinQ64;
typedef DynamicRMQ<long long, greater<long long> > RMaxQ64;
typedef DynamicRMQ<int, less<int> > RMinQ32;
typedef DynamicRMQ<int, greater<int> > RMaxQ32;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int N, M, Q;
cin >> N >> M >> Q;
vector<vi> G(N);
rep(i, M) {
int a, b;
cin >> a >> b;
--a;
--b;
G[a].push_back(b);
G[b].push_back(a);
}
auto tecc = TwoEdgeCC(G).get();
vi id(N);
rep(i, sz(tecc)) {
each(j, tecc[i]) {
id[j] = i;
}
}
int K = sz(tecc);
vector<vi> H(K);
rep(i, N)each(j, G[i]) {
int u = id[i], v = id[j];
if (u != v) {
H[u].push_back(v);
}
}
auto hl = HLDecomposition(H);
RMaxQ32 rmq(K, -1);
unordered_map<int, int> pos;
vector<set<int>> vals(K);
while (Q--) {
int t, x, y;
cin >> t >> x >> y;
if (t == 1) {
x = hl.id[id[x-1]];
vals[x].insert(y);
rmq.update(x, *vals[x].rbegin());
pos[x] = y;
} else {
x = hl.id[id[x - 1]], y = hl.id[id[y - 1]];
auto path = hl.goUpToLCA(x, y);
int ans = -1;
each(p, path) {
smax(ans, rmq.query(p.first, p.second));
}
cout << ans << endl;
if (ans != -1) {
int p = pos[ans], z = -1;
vals[p].erase(ans);
if (sz(vals[p]))z = *vals[p].rbegin();
rmq.update(p, z);
}
}
}
}