結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
tonegawa
|
| 提出日時 | 2020-05-13 08:32:50 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,760 ms / 4,500 ms |
| コード長 | 5,895 bytes |
| コンパイル時間 | 1,751 ms |
| コンパイル使用メモリ | 111,516 KB |
| 実行使用メモリ | 51,864 KB |
| 最終ジャッジ日時 | 2024-09-14 15:26:12 |
| 合計ジャッジ時間 | 12,697 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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 int ll;
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< int > 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(int idx, int 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(int idx, int par, int ×) {
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);
int t = 0;
dfs_hld(0, -1, t);
}
int la(int v, int 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];
}
}
int lca(int u, int 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(int u, int 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(int u, int 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;
vector<vll> dat;
vector<ll> INIT;
segtree(ll N, ll num){
INIT = vll{num, -1};
while(M<N) M*=2;
dat.resize(M*2-1, vll{num, -1});
}
void update(vll x, ll k, ll l=0, ll r=-1){
if(r==-1) r = M;
k+=M-1;
dat[k][0] = x[0], dat[k][1] = x[1];
while(k>0) {
k = (k-1)/2;
if(dat[k*2+2][0]>dat[k*2+1][0]){
dat[k][0] = dat[k*2+2][0], dat[k][1] = dat[k*2+2][1];
}else{
dat[k][0] = dat[k*2+1][0], dat[k][1] = dat[k*2+1][1];
}
}
}
vll 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];
vll A = query(a, b, k*2+1, l, (l+r)/2);
vll B = query(a, b, k*2+2, (l+r)/2, r);
return max(A, B);
}
};
#include <queue>
int main(int argc, char const *argv[]) {
ll a, b, c, n, m, q;std::cin >> n >> m >> q;
Graph G(SIZE);
re(i, m){
scanf("%d %d", &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<int>> T(SIZE, vector<int>());
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<int>>> hld(T);
hld.build();
segtree seg(SIZE, -1);
vector<priority_queue<ll>> max_cost(SIZE);
re(i, q){
scanf("%d %d %d", &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(vll{MAX, b}, x);});
}else{
b = cmp[b-1];
c = cmp[c-1];
vll q = hld.query(b, c, vll{-1, -1},
[&](ll x, ll y){return seg.query(x, y);},
[&](vll x, vll y){return max(x, y);}
);
printf("%d\n", q[0]);
if(q[0]!=-1) {
max_cost[q[1]].pop();
ll MAX = (!max_cost[q[1]].empty()?max_cost[q[1]].top():-1);
hld.add(q[1], q[1], [&](ll x, ll y){seg.update(vll{MAX, q[1]}, x);});
}
}
}
return 0;
}
tonegawa