結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
tonegawa
|
| 提出日時 | 2020-05-13 09:13:41 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 508 ms / 4,500 ms |
| コード長 | 5,977 bytes |
| コンパイル時間 | 1,515 ms |
| コンパイル使用メモリ | 104,668 KB |
| 実行使用メモリ | 49,876 KB |
| 最終ジャッジ日時 | 2024-09-14 15:27:37 |
| 合計ジャッジ時間 | 7,386 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 18 |
ソースコード
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <functional>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d> >(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
#define int long long
typedef long double ld;
using namespace std;
using Weight = int;
using Flow = int;
struct Edge {
int src, dst;
Weight weight;
Flow cap;
Edge() : src(0), dst(0), weight(0) {}
Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;
std::pair<std::vector<int>, Edges> bridge(const Graph& g) {
const int n = g.size();
int idx = 0, s = 0, t = 0, k = 0;
std::vector<int> ord(n, -1), onS(n), stk(n), roots(n), cmp(n);
Edges brdg;
std::function<void(int, int)> dfs = [&](int v, int u) {
ord[v] = idx++;
stk[s++] = v;
onS[v] = true;
roots[t++] = v;
for (auto& e : g[v]) {
int w = e.dst;
if (ord[w] == -1)
dfs(w, v);
else if (u != w && onS[w])
while (ord[roots[t - 1]] > ord[w]) --t;
}
if (v == roots[t - 1]) {
brdg.emplace_back(u, v, 0);
while (1) {
int w = stk[--s];
onS[w] = false;
cmp[w] = k;
if (v == w) break;
}
--t;
++k;
}
};
for (int u = 0; u < n; u++) {
if (ord[u] == -1) {
dfs(u, n);
brdg.pop_back();
}
}
return std::make_pair(cmp, brdg);
}
#define SIZE 100001
template< typename G >
struct HeavyLightDecomposition {
G &g;
vector<ll> sz, in, out, head, rev, par;
HeavyLightDecomposition(G &g) :
g(g), sz(SIZE), in(SIZE), out(SIZE), head(SIZE), rev(SIZE), par(SIZE) {}
void dfs_sz(ll idx, ll p) {
par[idx] = p;
sz[idx] = 1;
if(g[idx].size() && g[idx][0] == p) swap(g[idx][0], g[idx].back());
for(auto &to : g[idx]) {
if(to == p) continue;
dfs_sz(to, idx);
sz[idx] += sz[to];
if(sz[g[idx][0]] < sz[to]) swap(g[idx][0], to);
}
}
void dfs_hld(ll idx, ll par, ll ×) {
in[idx] = times++;
rev[in[idx]] = idx;
for(auto &to : g[idx]) {
if(to == par) continue;
head[to] = (g[idx][0] == to ? head[idx] : to);
dfs_hld(to, idx, times);
}
out[idx] = times;
}
void build() {
dfs_sz(0, -1);
ll t = 0;
dfs_hld(0, -1, t);
}
ll la(ll v, ll k) {
while(1) {
int u = head[v];
if(in[v] - k >= in[u]) return rev[in[v] - k];
k -= in[v] - in[u] + 1;
v = par[u];
}
}
ll lca(ll u, ll v) {
for(;; v = par[head[v]]) {
if(in[u] > in[v]) swap(u, v);
if(head[u] == head[v]) return u;
}
}
template< typename T, typename Q, typename F >
T query(ll u, ll v, const T &ti, const Q &q, const F &f, bool edge = false) {
T l = ti, r = ti;
for(;; v = par[head[v]]) {
if(in[u] > in[v]) swap(u, v), swap(l, r);
if(head[u] == head[v]) break;
l = f(q(in[head[v]], in[v] + 1), l);
}
return f(f(q(in[u] + edge, in[v] + 1), l), r);
// return {f(q(in[u] + edge, in[v] + 1), l), r};
}
template< typename Q >
void add(ll u, ll v, const Q &q, bool edge = false) {
for(;; v = par[head[v]]) {
if(in[u] > in[v]) swap(u, v);
if(head[u] == head[v]) break;
q(in[head[v]], in[v] + 1);
}
q(in[u] + edge, in[v] + 1);
}
};
//-------------------------------------------------------------------
struct segtree{
ll M=1, INIT;
vector<ll> dat;
segtree(ll N, ll num){
INIT = num;
while(M<N) M*=2;
for(int i=0;i<M*2-1;i++) dat.push_back(num);
}
void update(ll x, ll k, ll l=0, int r=-1){
if(r==-1) r = M;
k+=M-1;
dat[k] = x;
while(k>0) k = (k-1)/2, dat[k] = max(dat[k*2+1],dat[k*2+2]);
}
ll query(ll a, ll b=-1, ll k=0, ll l=0, ll r=-1){
if(r==-1) r = M;
if(b==-1) b = M;
if(r<=a || b<=l) return INIT;
if(a<=l && r<=b) return dat[k];
ll A = query(a, b, k*2+1, l, (l+r)/2);
ll B = query(a, b, k*2+2, (l+r)/2, r);
return max(A, B);
}
};
//-------------------------------------------------------------------
#include <queue>
signed main() {
ll a, b, c, n, m, q;std::cin >> n >> m >> q;
Graph G(SIZE);
re(i, m){
scanf("%lld %lld", &a, &b);
G[a-1].push_back(Edge(a-1, b-1, 1));
G[b-1].push_back(Edge(b-1, a-1, 1));
}
auto w = bridge(G);
vector<int> cmp = w.first;
vector<vector<ll>> T(SIZE, vector<ll>());
for(auto e:w.second){
int from = cmp[e.src];
int to = cmp[e.dst];
T[from].push_back(to);
T[to].push_back(from);
}
HeavyLightDecomposition<vector<vector<ll>>> hld(T);
hld.build();
segtree seg(SIZE, -1);
vector<priority_queue<ll>> max_cost(SIZE);
ll f = 1000000;
re(i, q){
scanf("%lld %lld %lld", &a, &b, &c);
if(a==1){
b = cmp[b-1];
max_cost[b].push(c);
ll MAX = max_cost[b].top();
hld.add(b, b, [&](ll x, ll y){
seg.update(
(MAX==-1?-1:MAX*f+b), x);
});
}else{
b = cmp[b-1];
c = cmp[c-1];
ll Q = hld.query(b, c, (ll)-1,
[&](ll x, ll y){return seg.query(x, y);},
[&](ll x, ll y){return max(x, y);}
);
//std::cout << Q << '\n';
if(Q==-1) printf("-1\n");
else{
printf("%lld\n", Q/f);
ll to = Q%f;
max_cost[to].pop();
ll MAX = (!max_cost[to].empty()?max_cost[to].top():-1);
hld.add(to, to, [&](ll x, ll y){
seg.update((MAX==-1?-1:MAX*f+to), x);
});
}
}
}
return 0;
}
tonegawa