Submission #1261315

#TimeUsernameProblemLanguageResultExecution timeMemory
1261315M_W_13Tourism (JOI23_tourism)C++20
100 / 100
1002 ms43512 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, n) for (int i = 0; i < (n); i++) #define st first #define nd second #define pb push_back const int MAXN = 1 << 18; const int MAXK = 20; int n, m, q; vector<pair<int, int>> graf[MAXN]; bool pomczy[MAXN]; int skok[MAXN][MAXK]; int depth[MAXN]; int pot2[MAXK]; int gleb[MAXN]; int preorder[MAXN]; int postorder[MAXN]; int seg[2 * MAXN]; pair<int, int> gdzie[MAXN]; pair<int, int> policz[MAXN]; int odp[MAXN]; int ojc[MAXN]; int C[MAXN]; bool pierw = true; int kt = 1; int kt2 = 1; struct pytaj { int l, r, nr, typ; }; vector<pytaj> dodaj; void upd(int v, int x) { v += MAXN; while (v > 0) { seg[v] += x; v /= 2; } } int query(int l, int r) { l += MAXN; r += MAXN; int ans = 0; while (l < r) { if ((l % 2) == 1) { ans += seg[l]; l++; } if ((r % 2) == 0) { ans += seg[r]; r--; } l /= 2; r /= 2; } if (l == r) { ans += seg[l]; } return ans; } void dfs(int v, int last, int dl) { // cout << "last = " << last << " v = " << v << " dl = " << dl << '\n'; policz[v] = gdzie[v]; depth[v] = depth[last] + dl; if (pierw) { gleb[v] = gleb[last] + 1; skok[v][0] = last; for (int k = 1; k < MAXK; k++) { skok[v][k] = skok[skok[v][k - 1]][k - 1]; } preorder[v] = kt; kt++; } for (auto syn: graf[v]) { if (syn.st == last) continue; dfs(syn.st, v, syn.nd); policz[v].st = max(policz[v].st, policz[syn.st].st); policz[v].nd = min(policz[v].nd, policz[syn.st].nd); } if (v != last) { dodaj.pb({policz[v].st, policz[v].nd, dl, 0}); } // cout << "w = " << v << " policz = " << policz[v].st << " " << policz[v].nd << " dl = " << dl << '\n'; if (pierw) { postorder[v] = kt2; kt2++; } if (v == last) { pierw = false; kt = 1; kt2 = 1; } } int lca(int a, int b) { if (gleb[a] > gleb[b]) { swap(a, b); } int k = MAXK - 1; while (gleb[b] > gleb[a]) { if ((gleb[b] - pot2[k]) >= gleb[a]) { b = skok[b][k]; } k--; } if (a == b) { return a; } k = MAXK - 1; while (skok[a][0] != skok[b][0]) { if (skok[a][k] != skok[b][k]) { a = skok[a][k]; b = skok[b][k]; } k--; } return skok[a][0]; } void znajdz(int l, int r, int sr) { for (int i = l; i < sr; i++) { gdzie[C[i]].st = i; } for (int i = r; i > sr; i--) { gdzie[C[i]].nd = i; } } void prepot2() { pot2[0] = 1; for (int k = 1; k < MAXK; k++) { pot2[k] = pot2[k - 1] * 2; } } bool por1(int a, int b) { return preorder[a] < preorder[b]; } void stworznowe(vector<int> &vec) { sort(vec.begin(), vec.end(), por1); for (auto x: vec) { pomczy[x] = true; } int sz = vec.size(); rep(i, sz - 1) { int v = lca(vec[i], vec[i + 1]); // cout << "lca = " << v << " a = " << vec[i] << " b = " << vec[i + 1] << endl; if (pomczy[v]) continue; pomczy[v] = true; vec.pb(v); } for (auto v: vec) { pomczy[v] = false; } sort(vec.begin(), vec.end(), por1); int last = vec[0]; sz = vec.size(); ojc[last] = last; for (int i = 1; i < sz; i++) { // cout << (int)vec.size() << endl; // cout << "PLS" << endl; // cout << "i = " << i << endl; // cout << "vec = " << vec[i] << endl; // cout << "XD" << endl; int v = vec[i]; // cout << "last = " << last << " v = " << v << endl; while (postorder[v] > postorder[last]) { last = ojc[last]; } // cout << "KONIEC" << endl; // cout << "tworzysz = " << " v = " << v << " last = " << last << " gl v = " << gleb[v] << " gl last = " << gleb[last] << endl; graf[v].pb({last, gleb[v] - gleb[last]}); // cout << (int)vec.size() << endl; graf[last].pb({v, gleb[v] - gleb[last]}); // cout << (int)vec.size() << endl; ojc[v] = last; // cout << (int)vec.size() << endl; last = v; // cout << (int)vec.size() << endl; // cout << (int)vec.size() << endl; // cout << "REL" << endl; // cout << (int)vec.size() << endl; } } vector<pytaj> pyt; bool por2(pytaj a, pytaj b) { pair<int, int> a2 = {a.r, a.typ}; pair<int, int> b2 = {b.r, b.typ}; return (a2 < b2); } void rob(int l, int r) { dodaj.clear(); // cout << "l = " << l << " r = " << r << endl; if (l == r) { for (auto p: pyt) { odp[p.nr] = 0; } return ; } int sr = (l + r)/2; vector<pytaj> pom1; vector<pytaj> pom2; vector<pytaj> ter; // cout << "CH1" << endl; for (auto p: pyt) { if (p.l <= sr && p.r >= sr) { ter.pb(p); } else if (p.r < sr) { pom1.pb(p); } else { pom2.pb(p); } } // cout << "CH2" << endl; pyt.clear(); vector<int> vec; for (int i = l; i <= r; i++) { int v = C[i]; // cout << "i = " << i << " v = " << v << endl; if (pomczy[v]) continue; pomczy[v] = true; vec.pb(v); } // cout << "CH3" << endl; stworznowe(vec); // cout << "CH4" << endl; for (auto v: vec) { gdzie[v] = {-1, m + 1}; policz[v] = {-1, m + 1}; } znajdz(l, r, sr); // for (auto v: vec) { // cout << "v = " << v << " l = " << gdzie[v].st << " r = " << gdzie[v].nd << '\n'; // } // cout << "CH5" << endl; int w = C[sr]; // cout << "w = " << w << endl; depth[w] = 0; // cout << "START" << endl; // for (auto v: vec) { // cout << "v = " << v << " l = " << gdzie[v].st << " r = " << gdzie[v].nd << '\n'; // } dfs(w, w, 0); // for (auto v: vec) { // cout << "v = " << v << " l = " << policz[v].st << " r = " << policz[v].nd << '\n'; // } // cout << "XD" << endl; for (auto p: dodaj) { ter.pb(p); // cout << "L = " << p.l << " R = " << p.r << " liczba = " << p.nr << endl; } // cout << "CH6" << endl; sort(ter.begin(), ter.end(), por2); for (auto p: ter) { if (p.typ == 0) { if (p.l >= 0) { upd(p.l, p.nr); } } } // cout << "CH7" << endl; int pomoc = 0; for (auto p: ter) { if (p.typ == 0) { if (p.l >= 0) { upd(p.l, -p.nr); } pomoc += p.nr; } else { // cout << "PYYYYTAAAAAANIEEEE = " << p.l << " " << p.r << '\n'; int ile = query(p.l, sr); odp[p.nr] = pomoc + ile; } } // cout << "CH8" << endl; ter.clear(); for (auto v: vec) { graf[v].clear(); } vec.clear(); pyt.clear(); for (auto p: pom1) { pyt.pb(p); } pom1.clear(); rob(l, sr); pyt.clear(); for (auto p: pom2) { pyt.pb(p); } rob(sr + 1, r); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); prepot2(); cin >> n >> m >> q; rep(i, n - 1) { int a, b; cin >> a >> b; graf[a].pb({b, 1}); graf[b].pb({a, 1}); } dfs(1, 1, 0); for (int v = 1; v <= n; v++) { graf[v].clear(); } rep(i, m) { cin >> C[i]; } rep(i, q) { int l, r; cin >> l >> r; l--; r--; pyt.pb({l, r, i, 1}); } // for (auto p: pyt) { // cout << p.l << " " << p.r << '\n'; // } rob(0, m - 1); rep(i, q) { odp[i]++; cout << odp[i] << '\n'; } return 0; }
#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...