結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
tonegawa
|
| 提出日時 | 2020-05-13 08:41:30 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 5,895 bytes |
| コンパイル時間 | 1,612 ms |
| コンパイル使用メモリ | 107,296 KB |
| 実行使用メモリ | 38,680 KB |
| 最終ジャッジ日時 | 2024-09-14 15:26:26 |
| 合計ジャッジ時間 | 9,488 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 2 RE * 16 |
ソースコード
#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;
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, 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>
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("%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<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);
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*f+b, x);});
}else{
b = cmp[b-1];
c = cmp[c-1];
ll q = hld.query(b, c, -1,
[&](ll x, ll y){return seg.query(x, y);},
[&](ll x, ll y){return max(x, y);}
);
if(q==-1) printf("-1\n");
if(q!=-1) {
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*f+to, x);});
}
}
}
return 0;
}
tonegawa