Submission #781945

#TimeUsernameProblemLanguageResultExecution timeMemory
781945peijarTourism (JOI23_tourism)C++17
100 / 100
3038 ms107288 KiB
#include <bits/stdc++.h> #define int long long using namespace std; string to_string(string s) { return s; } template <typename T> string to_string(T v) { bool first = true; string res = "["; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } res += "]"; return res; } void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << to_string(H); dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif template <class T> class Fenwick { public: int lim; vector<T> bit; Fenwick(int n) : lim(n + 1), bit(lim) {} void upd(int pos, T val) { for (pos++; pos < lim; pos += pos & -pos) bit[pos] += val; } T sum(int r) { // < r T ret = 0; for (; r; r -= r & -r) ret += bit[r]; return ret; } T sum(int l, int r) { // [l, r) return sum(r) - sum(l); } }; template <class T> struct RMQ { vector<vector<T>> jmp; RMQ(const vector<T> &V) : jmp(1, V) { for (int pw = 1, k = 1; pw * 2 <= (int)V.size(); pw *= 2, ++k) { jmp.emplace_back((int)V.size() - pw * 2 + 1); for (int j = 0; j < (int)jmp[k].size(); ++j) jmp[k][j] = max(jmp[k - 1][j], jmp[k - 1][j + pw]); } } T query(int a, int b) { // [a, b) assert(a < b); int dep = 31 - __builtin_clz(b - a); return max(jmp[dep][a], jmp[dep][b - (1 << dep)]); } }; const int MAXN = 4e5 + 1; const int MAXP = 20; int iDeb[MAXN], iFin[MAXN], lazy[MAXN]; vector<int> adj[MAXN]; int sz[MAXN]; int depth[MAXN]; int par[MAXP][MAXN]; int heavyPar[MAXN]; int tin[MAXN]; int Time; void push(int node) { if (iDeb[node] < iFin[node] and lazy[node] != -1) { lazy[2 * node] = lazy[2 * node + 1] = lazy[node]; lazy[node] = -1; } } void build(int node, int l, int r, int defaultVal) { iDeb[node] = l, iFin[node] = r; lazy[node] = defaultVal; if (l == r) return; int m = (l + r) / 2; build(2 * node, l, m, defaultVal); build(2 * node + 1, m + 1, r, defaultVal); } void update(int node, int l, int r, int val) { push(node); if (l > iFin[node] or iDeb[node] > r) return; if (iDeb[node] >= l and iFin[node] <= r) { lazy[node] = val; push(node); return; } update(2 * node, l, r, val); update(2 * node + 1, l, r, val); } int query(int node, int pos) { push(node); if (pos > iFin[node] or pos < iDeb[node]) return 0; if (iDeb[node] == iFin[node]) return lazy[node]; return query(2 * node, pos) + query(2 * node + 1, pos); } void dfsHLD(int u, int p) { sz[u] = 1; par[0][u] = p; for (int i = 0; i < MAXP - 1; ++i) par[i + 1][u] = par[i][par[i][u]]; int largest = -1; for (int v : adj[u]) if (v != p) { depth[v] = depth[u] + 1; dfsHLD(v, u); sz[u] += sz[v]; if (largest == -1 or sz[largest] < sz[v]) largest = v; } if (largest != -1) for (int i = 1; i < (int)adj[u].size(); ++i) if (adj[u][i] == largest) { swap(adj[u][i], adj[u][0]); break; } } void dfs(int u, int p) { tin[u] = Time++; for (int i = 0; i < (int)adj[u].size(); ++i) { int v = adj[u][i]; if (v == p) continue; if (!i) heavyPar[v] = heavyPar[u]; else heavyPar[v] = v; dfs(v, u); } } int getLca(int u, int v) { if (depth[u] < depth[v]) swap(u, v); int d = depth[u] - depth[v]; for (int p = 0; p < MAXP; ++p) if ((1 << p) & d) u = par[p][u]; if (u == v) return u; for (int p = MAXP - 1; p >= 0; --p) { int uu = par[p][u], vv = par[p][v]; if (uu != vv) u = uu, v = vv; } return par[0][u]; } signed main(void) { ios_base::sync_with_stdio(false); cin.tie(0); int nbSommets, nbSites, nbRequetes; cin >> nbSommets >> nbSites >> nbRequetes; for (int i = 0; i < nbSommets - 1; ++i) { int u, v; cin >> u >> v; --u, --v; adj[u].push_back(v); adj[v].push_back(u); } dfsHLD(0, 0); dfs(0, 0); vector<int> sites(nbSites); for (int &x : sites) { cin >> x; --x; } vector<pair<int, int>> inRMQ(nbSites); for (int i = 0; i < nbSites; ++i) inRMQ[i] = pair(tin[sites[i]], sites[i]); RMQ<pair<int, int>> maxSight(inRMQ); for (auto &[t, u] : inRMQ) t *= -1; RMQ<pair<int, int>> minSight(inRMQ); vector<int> solRequete(nbRequetes); vector<vector<pair<int, int>>> queriesAt(nbSites); for (int iRequete = 0; iRequete < nbRequetes; ++iRequete) { int l, r; cin >> l >> r; --l, --r; queriesAt[l].emplace_back(r, iRequete); } for (int u = 0; u < nbSommets; ++u) dbg(u + 1, heavyPar[u] + 1); build(1, 0, nbSommets - 1, nbSites); Fenwick<int> withVal(nbSites + 1); withVal.upd(nbSites, nbSommets); for (int L = nbSites - 1; L >= 0; --L) { int u = sites[L]; while (true) { int v = u; int val = query(1, tin[u]); for (int p = MAXP - 1; p >= 0; --p) if (val == query(1, tin[par[p][v]])) v = par[p][v]; dbg(u + 1, v + 1, val); withVal.upd(val, -(depth[u] - depth[v] + 1)); if (!v) break; u = par[0][v]; } u = sites[L]; while (true) { update(1, tin[heavyPar[u]], tin[u], L); dbg("UPDATE"s, 1 + heavyPar[u], 1 + u, L); withVal.upd(L, depth[u] - depth[heavyPar[u]] + 1); if (!heavyPar[u]) break; u = par[0][heavyPar[u]]; } for (auto [r, iRequete] : queriesAt[L]) { solRequete[iRequete] = withVal.sum(r + 1); int fst = minSight.query(L, r + 1).second; int lst = maxSight.query(L, r + 1).second; solRequete[iRequete] -= depth[getLca(fst, lst)]; } } for (int x : solRequete) cout << x << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...