제출 #646766

#제출 시각아이디문제언어결과실행 시간메모리
646766ghostwriterValley (BOI19_valley)C++14
36 / 100
2840 ms262144 KiB
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include <debug.h>
#else
#define debug(...)
#endif
#define ft front
#define bk back
#define st first
#define nd second
#define ins insert
#define ers erase
#define pb push_back
#define pf push_front
#define _pb pop_back
#define _pf pop_front
#define lb lower_bound
#define ub upper_bound
#define mtp make_tuple
#define bg begin
#define ed end
#define all(x) (x).bg(), (x).ed()
#define sz(x) (int)(x).size()
// #define int long long
typedef long long ll; typedef unsigned long long ull;
typedef double db; typedef long double ldb;
typedef pair<int, int> pi; typedef pair<ll, ll> pll;
typedef vector<int> vi; typedef vector<ll> vll; typedef vector<pi> vpi; typedef vector<pll> vpll;
typedef string str;
template<typename T> T gcd(T a, T b) { return (b == 0? a : gcd(b, a % b)); }
template<typename T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
#define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
#define FOS(i, r, l) for (int (i) = (r); (i) >= (l); --(i))
#define FRN(i, n) for (int (i) = 0; (i) < (n); ++(i))
#define FSN(i, n) for (int (i) = (n) - 1; (i) >= 0; --(i))
#define EACH(i, x) for (auto &(i) : (x))
#define WHILE while
#define file "TEST"
mt19937 rd(chrono::steady_clock::now().time_since_epoch().count());
ll rand(ll l, ll r) { return uniform_int_distribution<ll>(l, r)(rd); }
/*
----------------------------------------------------------------
    END OF TEMPLATE
----------------------------------------------------------------
    Tran The Bao - ghostwriter
    Training for VOI23 gold medal
----------------------------------------------------------------
    DIT ME TTB NON
----------------------------------------------------------------
*/
#define matrix vector<vpi>
const ll oo = (ll)1e18 + 5;
const int T = 8e5 + 1;
const int N = 1e5 + 1;
int n, s, q, e, p[N], tin[N], tout[N], s1[N], c[N], query[N], timer = 0, root = 0;
ll h[N], tr[T], ans[N];
matrix pre[N], suf[N], seg[N];
vpi edge, adj[N];
vpll a[N], a1[N];
vi vertex, adj1[N];
map<int, ll> dis[N];
void upd(int i, int l, int r, int q, ll v) {
	if (r < q || l > q) return;
	if (l == r) {
		tr[i] = v;
		return;
	}
	int mid = l + (r - l) / 2;
	upd(i * 2, l, mid, q, v);
	upd(i * 2 + 1, mid + 1, r, q, v);
	tr[i] = min(tr[i * 2], tr[i * 2 + 1]);
}
ll get(int i, int l, int r, int ql, int qr) {
	if (r < ql || l > qr) return oo;
	if (ql <= l && r <= qr) return tr[i];
	int mid = l + (r - l) / 2;
	return min(get(i * 2, l, mid, ql, qr), get(i * 2 + 1, mid + 1, r, ql, qr));
}
void dfs(int u, int p) {
	tin[u] = ++timer;
	EACH(j, adj[u]) {
		int v = j.st;
		if (v == p) continue;
		dfs(v, u);
	}
	tout[u] = ++timer;
}
bool isc(int a, int b) { return tin[a] >= tin[b] && tout[b] >= tout[a]; }
int getp(pi a) {
	if (isc(a.st, a.nd)) return a.st;
	return a.nd;
}
void dfs1(int u, int p) {
	s1[u] = 1;
	EACH(j, adj[u]) {
		int v = j.st;
		if (c[v] || v == p) continue;
		dfs1(v, u);
		s1[u] += s1[v];
	}
}
void dfs2(int u, int p) {
	vertex.pb(u);
	EACH(j, adj[u]) {
		int v = j.st, w = j.nd;
		if (c[v] || v == p) continue;
		h[v] = h[u] + w;
		dfs2(v, u);
	}
}
int fct(int u, int p, int total) {
	EACH(j, adj[u]) {
		int v = j.st; 
		if (c[v] || v == p) continue;
		if (s1[v] > total / 2) return fct(v, u, total);
	}
	return u;
}
void merge(vpll &a, vpll &b) { // by tin
	int l = 0;
	vpll ans;
	EACH(i, a) {
		WHILE(l < sz(b) && tin[b[l].st] < tin[i.st]) ans.pb(b[l++]);
		ans.pb(i);
	}
	WHILE(l < sz(b)) ans.pb(b[l++]);
	a = ans;
}
void merge1(vpll &a, vpll &b) { // by tout
	int l = 0;
	vpll ans;
	EACH(i, a) {
		WHILE(l < sz(b) && tout[b[l].st] < tout[i.st]) ans.pb(b[l++]);
		ans.pb(i);
	}
	WHILE(l < sz(b)) ans.pb(b[l++]);
	a = ans;
}
int centroid(int u) {
	dfs1(u, 0);
	int ct = fct(u, 0, s1[u]);
	c[ct] = 1;
	a[ct].pb({ct, 0});
	a1[ct].pb({ct, 0});
	vertex.clear();
	h[ct] = 0;
	dfs2(ct, 0);
	EACH(i, vertex) dis[ct][i] = h[i];
	EACH(j, adj[ct]) {
		int v = j.st;
		if (c[v]) continue;
		int nxt = centroid(v);
		p[nxt] = ct;
		vpll &an = a[nxt], &a1n = a1[nxt];
		merge(a[ct], an);
		merge1(a1[ct], a1n);
		adj1[ct].pb(nxt);
	}
	EACH(i, a[ct]) i.nd = dis[ct][i.st];
	EACH(i, a1[ct]) i.nd = dis[ct][i.st];
	int m = sz(a[ct]);
	pre[ct].resize(m);
	suf[ct].resize(m);
	seg[ct].resize(m);
	return ct;
}
void add(int i, int R, int u, int id) {
	int m = sz(a[u]);
	int l = 0, r = m - 1, ans1 = -1, ans2 = -1, ans3 = -1;
	WHILE(l <= r) {
		int mid = l + (r - l) / 2;
		if (tin[a[u][mid].st] < tin[i]) {
			ans1 = mid;
			l = mid + 1;
		}
		else r = mid - 1;
	}
	l = 0; r = m - 1;
	WHILE(l <= r) {
		int mid = l + (r - l) / 2;
		if (tout[a1[u][mid].st] > tout[i]) {
			ans2 = mid;
			r = mid - 1;
		}
		else l = mid + 1;
	}
	l = 0; r = m - 1;
	WHILE(l <= r) {
		int mid = l + (r - l) / 2;
		if (tout[a1[u][mid].st] <= tout[i]) {
			ans3 = mid;
			l = mid + 1;
		}
		else r = mid - 1;
	}
	if (isc(R, i)) {
		if (ans3 != -1) seg[u][ans3].pb({id, tin[i]});
	}
	else {
		if (ans1 != -1) pre[u][ans1].pb({id, -1});
		if (ans2 != -1) suf[u][ans2].pb({id, -1});
	}
	if (p[u]) add(i, R, p[u], id);
}
void process(int u) {
	int m = sz(a[u]);
	ll Min = oo;
	FOS(i, m - 1, 0) {
		int cur = a1[u][i].st;
		if (cur == e) Min = min(Min, -oo);
		else if (c[cur]) Min = min(Min, a1[u][i].nd);
		EACH(j, suf[u][i]) {
			int v = j.st;
			ans[v] = min(ans[v], dis[u][query[v]] + Min);
		}
	}
	Min = oo;
	FOR(i, 0, m - 1) {
		int cur = a[u][i].st;
		if (cur == e) Min = min(Min, -oo);
		else if (c[cur]) Min = min(Min, a[u][i].nd);
		EACH(j, pre[u][i]) {
			int v = j.st;
			ans[v] = min(ans[v], dis[u][query[v]] + Min);
		}
	}
	FOR(i, 0, m - 1) {
		int cur = a1[u][i].st;
		if (cur == e) upd(1, 1, 2 * n, tin[cur], -oo);
		else if (c[cur]) upd(1, 1, 2 * n, tin[cur], a1[u][i].nd);
		EACH(j, seg[u][i]) {
			int v = j.st, t = j.nd;
			ans[v] = min(ans[v], dis[u][query[v]] + get(1, 1, 2 * n, t, 2 * n));
		}
	}
	FOR(i, 0, m - 1) {
		int cur = a1[u][i].st;
		upd(1, 1, 2 * n, tin[cur], oo);
	}
	EACH(v, adj1[u]) process(v);
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    // freopen(file".inp", "r", stdin);
    // freopen(file".out", "w", stdout);
    cin >> n >> s >> q >> e;
    FOR(i, 1, n << 3) tr[i] = oo;
    edge.pb({0, 0});
    FOR(i, 1, n - 1) {
    	int u, v, w;
    	cin >> u >> v >> w;
    	edge.pb({u, v});
    	adj[u].pb({v, w});
    	adj[v].pb({u, w});
    }
    dfs(1, 0);
    root = centroid(1);
    memset(c, 0, sizeof c);
    FOR(i, 1, s) {
    	int ci;
    	cin >> ci;
    	c[ci] = 1;
    }
    FOR(j, 1, q) {
    	ans[j] = oo;
    	int i, r;
    	cin >> i >> r;
    	add(getp(edge[i]), r, r, j);
    	query[j] = r;
    }
    process(root);
    FOR(i, 1, q)
    	if (ans[i] < 0) cout << "escaped\n";
    	else if (ans[i] < oo) cout << ans[i] << '\n';
    	else cout << "oo\n";
    return 0;
}
/*
5 2 3 1
1 2 3
1 3 2
3 4 1
3 5 2
2
4
2 2
2 5
4 5
----------------------------------------------------------------
From Benq:
    stuff you should look for
        * int overflow, array bounds
        * special cases (n=1?)
        * do smth instead of nothing and stay organized
        * WRITE STUFF DOWN
        * DON'T GET STUCK ON ONE APPROACH
----------------------------------------------------------------
*/

컴파일 시 표준 에러 (stderr) 메시지

valley.cpp: In function 'void dfs(int, int)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:82:2: note: in expansion of macro 'EACH'
   82 |  EACH(j, adj[u]) {
      |  ^~~~
valley.cpp: In function 'void dfs1(int, int)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:96:2: note: in expansion of macro 'EACH'
   96 |  EACH(j, adj[u]) {
      |  ^~~~
valley.cpp: In function 'void dfs2(int, int)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:105:2: note: in expansion of macro 'EACH'
  105 |  EACH(j, adj[u]) {
      |  ^~~~
valley.cpp: In function 'int fct(int, int, int)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:113:2: note: in expansion of macro 'EACH'
  113 |  EACH(j, adj[u]) {
      |  ^~~~
valley.cpp: In function 'void merge(vpll&, vpll&)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:123:2: note: in expansion of macro 'EACH'
  123 |  EACH(i, a) {
      |  ^~~~
valley.cpp: In function 'void merge1(vpll&, vpll&)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:133:2: note: in expansion of macro 'EACH'
  133 |  EACH(i, a) {
      |  ^~~~
valley.cpp: In function 'int centroid(int)':
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:149:2: note: in expansion of macro 'EACH'
  149 |  EACH(i, vertex) dis[ct][i] = h[i];
      |  ^~~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:150:2: note: in expansion of macro 'EACH'
  150 |  EACH(j, adj[ct]) {
      |  ^~~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:160:2: note: in expansion of macro 'EACH'
  160 |  EACH(i, a[ct]) i.nd = dis[ct][i.st];
      |  ^~~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:161:2: note: in expansion of macro 'EACH'
  161 |  EACH(i, a1[ct]) i.nd = dis[ct][i.st];
      |  ^~~~
valley.cpp: In function 'void process(int)':
valley.cpp:34:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   34 | #define FOS(i, r, l) for (int (i) = (r); (i) >= (l); --(i))
      |                               ^
valley.cpp:209:2: note: in expansion of macro 'FOS'
  209 |  FOS(i, m - 1, 0) {
      |  ^~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:213:3: note: in expansion of macro 'EACH'
  213 |   EACH(j, suf[u][i]) {
      |   ^~~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:219:2: note: in expansion of macro 'FOR'
  219 |  FOR(i, 0, m - 1) {
      |  ^~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:223:3: note: in expansion of macro 'EACH'
  223 |   EACH(j, pre[u][i]) {
      |   ^~~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:228:2: note: in expansion of macro 'FOR'
  228 |  FOR(i, 0, m - 1) {
      |  ^~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:232:3: note: in expansion of macro 'EACH'
  232 |   EACH(j, seg[u][i]) {
      |   ^~~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:237:2: note: in expansion of macro 'FOR'
  237 |  FOR(i, 0, m - 1) {
      |  ^~~
valley.cpp:37:31: warning: unnecessary parentheses in declaration of 'v' [-Wparentheses]
   37 | #define EACH(i, x) for (auto &(i) : (x))
      |                               ^
valley.cpp:241:2: note: in expansion of macro 'EACH'
  241 |  EACH(v, adj1[u]) process(v);
      |  ^~~~
valley.cpp: In function 'int main()':
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:248:5: note: in expansion of macro 'FOR'
  248 |     FOR(i, 1, n << 3) tr[i] = oo;
      |     ^~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:250:5: note: in expansion of macro 'FOR'
  250 |     FOR(i, 1, n - 1) {
      |     ^~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:260:5: note: in expansion of macro 'FOR'
  260 |     FOR(i, 1, s) {
      |     ^~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:265:5: note: in expansion of macro 'FOR'
  265 |     FOR(j, 1, q) {
      |     ^~~
valley.cpp:33:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(i, l, r) for (int (i) = (l); (i) <= (r); ++(i))
      |                               ^
valley.cpp:273:5: note: in expansion of macro 'FOR'
  273 |     FOR(i, 1, q)
      |     ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...