Submission #1030731

#TimeUsernameProblemLanguageResultExecution timeMemory
1030731NeroZeinTourism (JOI23_tourism)C++17
10 / 100
5104 ms326664 KiB
#include "bits/stdc++.h" using namespace std; #pragma GCC optimize("Ofast,fast-math,unroll-loops") #pragma GCC target("avx2,fma") #ifdef Nero #include "Deb.h" #else #define debug(...) #endif const int B = 400; const int LOG = 18; const int N = 1e5 + 5; int n, m, q; int c[N]; int dep[N]; int idd, id[N]; vector<int> g[N]; int spa[LOG][N * 2]; void dfs(int v, int p) { id[v] = idd; spa[0][idd++] = v; for (int u : g[v]) { if (u == p) { continue; } dep[u] = dep[v] + 1; dfs(u, v); spa[0][idd++] = v; } } int get(int l, int r) { int lg = 31 - __builtin_clz(r - l + 1); int u = spa[lg][l], v = spa[lg][r - (1 << lg) + 1]; return dep[u] < dep[v] ? u : v; } int distance(int u, int v) { int l = id[u], r = id[v]; if (l > r) { swap(l, r); } int lca = get(l, r); int ret = dep[u] + dep[v] - 2 * dep[lca]; return ret; } int cnt[B][N]; int in_id[N * 2]; int ans[N]; int res[B]; int pre[B][N], nxt[B][N]; vector<pair<int, int>> qs[N]; void preprocess() {//B * N for (int ver = 0; ver * B < m; ++ver) {//M / B (B) for (int r = ver * B; r < m; ++r) {//M int v = c[r]; cnt[ver][v]++; in_id[id[v]] = v; } vector<int> ord; for (int i = 0; i < idd; ++i) {//2 * N if (in_id[i] != 0) { ord.push_back(in_id[i]); in_id[i] = 0; } } //debug(ord); //cerr << '\n'; for (int i = 1; i < (int) ord.size(); ++i) {//N int u = ord[i - 1], v = ord[i]; res[ver] += distance(u, v); pre[ver][v] = u; nxt[ver][u] = v; } nxt[ver][ord.back()] = ord[0]; pre[ver][ord[0]] = ord.back(); res[ver] += distance(ord[0], ord.back()); } } void back(int r) { //debug(r); for (int ver = 0; ver * B <= r; ++ver) {//M / B int v = c[r]; if (--cnt[ver][v] > 0) { continue; } //int old = res[ver]; int cpre = pre[ver][v]; int cnxt = nxt[ver][v]; if (cpre != 0) { res[ver] -= distance(v, cpre); } if (cnxt != 0) { res[ver] -= distance(v, cnxt); } if (cpre != 0 && cnxt != 0) { nxt[ver][cpre] = cnxt; pre[ver][cnxt] = cpre; res[ver] += distance(cpre, cnxt); } //debug(ver, v, cpre, cnxt, old, res[ver]); } //cerr << '\n'; } int cnt2[N]; vector<int> clean; int curpre[N], curnxt[N]; void check(int v) { if (curpre[v] == 0 && curnxt[v] == 0) { clean.push_back(v); } } void rem(int ver, int cl, int& ret) { int v = c[cl]; check(v); if (cnt2[v] == 0) { cnt2[v] = cnt[ver][v]; } if (curpre[v] == 0) { curpre[v] = pre[ver][v]; } if (curnxt[v] == 0) { curnxt[v] = nxt[ver][v]; } if (--cnt2[v] != 0) { return; } int cpre = curpre[v]; int cnxt = curnxt[v]; if (cpre != 0) { ret -= distance(v, cpre); } if (cnxt != 0) { ret -= distance(v, cnxt); } if (cpre != 0 && cnxt != 0) { check(cpre); check(cnxt); curpre[cnxt] = cpre; curnxt[cpre] = cnxt; ret += distance(cpre, cnxt); } } int qry(int l) { int ver = l / B; int ret = res[ver]; int cl = ver * B; assert(l - cl < B); while (cl < l) { rem(ver, cl, ret); cl++; } return ret; } void cleanup() { for (int v : clean) { cnt2[v] = curpre[v] = curnxt[v] = 0; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m >> q; for(int i = 0; i < n - 1; ++i) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } dfs(1, 1); for (int j = 1; j < LOG; ++j) { for (int i = 0; i + (1 << j) <= idd; ++i) { int u = spa[j - 1][i], v = spa[j - 1][i + (1 << (j - 1))]; spa[j][i] = (dep[u] < dep[v] ? u : v); } } for (int i = 0; i < m; ++i) { cin >> c[i]; } preprocess(); for (int i = 0; i < q; ++i) { int l, r; cin >> l >> r; --l, --r; qs[r].push_back({l, i}); } for (int r = m - 1; r >= 0; --r) { for (auto [ql, qi] : qs[r]) { ans[qi] = (qry(ql) + 2) / 2; cleanup(); } back(r); } for (int i = 0; i < q; ++i) { cout << ans[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...