Submission #793765

#TimeUsernameProblemLanguageResultExecution timeMemory
793765vjudge1Tourism (JOI23_tourism)C++17
18 / 100
367 ms24452 KiB
#include<bits/stdc++.h> using namespace std; using ll = long long; const int N = 1e5 + 10; const int M = (1 << 18); // segment Sum + update in pos int segSum[2 * M]; void update(int pos, int val) { for(segSum[pos += M] += val; pos > 1; pos >>= 1) { segSum[pos >> 1] = segSum[pos] + segSum[(pos ^ 1)]; } } int get(int ql, int qr) { int res = 0; for(ql += M, qr += M + 1; ql < qr; ql >>= 1, qr >>= 1) { if(ql & 1) res += segSum[ql++]; if(qr & 1) res += segSum[--qr]; } return res; } int n, m, q; vector<int> g[N]; vector<pair<int, int>> e; int sm[N]; int tin[N], tout[N], anc[N][17], depth[N], T; void calc(int s, int p) { for(int to : g[s]) { if(to == p) continue; calc(to, s); sm[s] += sm[to]; } } void precalc(int s, int p) { tin[s] = T++; anc[s][0] = p; for(int i = 1; i < 17; i++) anc[s][i] = anc[anc[s][i - 1]][i - 1]; for(int to : g[s]) { if(to == p) continue; depth[to] = depth[s] + 1; precalc(to, s); } tout[s] = T++; } bool up(int u, int v) { return tin[u] <= tin[v] && tout[u] >= tout[v]; } int lca(int u, int v) { if(up(u, v)) return u; if(up(v, u)) return v; for(int i = 16; i >= 0; i--) { if(!up(anc[u][i], v)) u = anc[u][i]; } return anc[u][0]; } struct query { int l, r, i; }; template<typename T> struct SprarseTable { int len; vector<vector<T>> st; void init(vector<T> &a) { len = (int)a.size(); int mxpw = 32 - __builtin_clz(len); st.resize(mxpw); st[0] = a; for(int k = 1; k < mxpw; k++) { st[k].resize(len - (1 << k) + 1); for(int i = 0; i < (int)st[k].size(); i++) { st[k][i] = lca(st[k - 1][i], st[k - 1][i + (1 << (k - 1))]); } } } T get(int l, int r) { int mxpw = 31 - __builtin_clz(r - l + 1); return lca(st[mxpw][l], st[mxpw][r - (1 << mxpw) + 1]); } }; int curAns; void add(int ver) { if(get(tin[ver], tout[ver]) == 0) curAns++; int u = ver; for(int i = 16; i >= 0; i--) { if(get(tin[ anc[u][i] ], tout[ anc[u][i] ]) == 0) u = anc[u][i]; } curAns += depth[ver] - depth[u]; update(tin[ver], +1); } void del(int ver) { update(tin[ver], -1); int u = ver; for(int i = 16; i >= 0; i--) { if(get(tin[ anc[u][i] ], tout[ anc[u][i] ]) == 0) u = anc[u][i]; } curAns -= depth[ver] - depth[u]; if(get(tin[ver], tout[ver]) == 0) curAns--; } vector<query> qr; int ans[N]; int main() { ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); 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); e.push_back({u, v}); } vector<int> ver(m + 1); for(int i = 1; i <= m; i++) cin >> ver[i]; precalc(1, 1); for(int i = 0; i < q; i++) { query c; cin >> c.l >> c.r; c.i = i; qr.push_back(c); } SprarseTable<int> lc; lc.init(ver); // sort(qr.begin(), qr.end(), [](query a, query b) {return (a.l < b.l);}); int curL = 1, curR = 0; for(query c : qr) { while(curR < c.r) { add(ver[++curR]); } while(curL < c.l) { del(ver[curL++]); } // cout << lc.get(c.l, c.r) << '\n'; ans[c.i] = curAns - depth[lc.get(c.l, c.r)]; } for(int i = 0; i < q; i++) cout << ans[i] << '\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...