Submission #806978

#TimeUsernameProblemLanguageResultExecution timeMemory
806978lukameladzeTourism (JOI23_tourism)C++17
34 / 100
597 ms91692 KiB
# include <bits/stdc++.h> using namespace std; #define f first #define s second //#define int long long #define ll long long #define pii pair <int, int> #define pb push_back #define ai3 array <int, 3> const int N = 3e5 + 5; int n, m, q,in[N], a[N], out[N], tin, lv[N], par[N][20]; vector <int> v[N]; vector < pii > updates; void dfs(int a, int p) { in[a] = ++tin; lv[a] = lv[p] + 1; par[a][0] = p; for (int i = 1; i <= 18; i++) { par[a][i] = par[par[a][i - 1]][i - 1]; } for (int to : v[a]) { if (to == p) continue; dfs(to, a); } out[a] = tin; } int upper(int a, int b) { return (in[a] <= in[b] && out[a] >= out[b]); } int lca(int a, int b) { if (upper(a, b)) return a; for (int i = 18; i >= 0; i--) { if (par[a][i] && !upper(par[a][i], b)) a = par[a][i]; } return par[a][0]; } bool cmp(int a, int b) { return in[a] < in[b]; } int parent[N], added[N],added1[N]; vector <int> g[N]; void dfs1(int a, int p) { parent[a] = p; for (int to : g[a]) { if (to == p) continue; dfs1(to, a); } } int tree[N]; void upd(int idx, int val) { updates.pb({idx, val}); for (int i = idx; i < N; i+=i&(-i)) { tree[i] += val; } } int getans(int idx) { int pas = 0; for (int i = idx; i > 0; i-=i&(-i)) { pas += tree[i]; } return pas; } vector <ai3> cur_q[N]; int sum[N], ans[N]; void solve(int l, int r, vector <ai3> que) { if (l > r || !que.size()) return ; vector <ai3> quel, quer; int mid = (l + r) / 2; for (ai3 sth : que) { if (sth[0] > mid) quer.pb(sth); else if (sth[1] <= mid) quel.pb(sth); else cur_q[sth[1]].pb(sth); } // building virtual tree, (not the most efficient way) vector <int> vert, fv; for (int i = l; i <= r; i++) { vert.pb(a[i]); } // remove duplicates, sort by in sort(vert.begin(), vert.end()); vert.resize(unique(vert.begin(), vert.end()) - vert.begin()); sort(vert.begin(), vert.end(), cmp); int sz = (int)vert.size(); for (int i = 1; i < sz; i++) { vert.pb(lca(vert[i - 1], vert[i])); } sort(vert.begin(), vert.end()); vert.resize(unique(vert.begin(), vert.end()) - vert.begin()); sort(vert.begin(), vert.end(), cmp); for (int i = 1; i < (int)vert.size(); i++) { // Virtual tree edges int lc = lca(vert[i - 1], vert[i]); g[lc].pb(vert[i]); g[vert[i]].pb(lc); } dfs1(a[mid], 0); for (int x : vert) { added[x] = 0; added1[x] = 0; } sum[mid] = 0; added[a[mid]] = added1[a[mid]] = 1; for (int i = mid - 1; i >= l; i--) { int cur = a[i]; int vl = 0; //if (l == 4 && r == 6) cout<<"--- "<<i<<"\n"; while (!added[cur]) { added[cur] = i; // if (l == 4 && r == 6) cout<<cur<<" "<<parent[cur]<<" "<<abs(lv[cur] - lv[parent[cur]])<<"\n"; vl += abs(lv[cur] - lv[parent[cur]]); cur = parent[cur]; } sum[i] = sum[i + 1] + vl; } for (int i = mid + 1; i <= r; i++) { int cur = a[i]; while (!added1[cur]) { if (added[cur] != mid) upd(added[cur] + 1, abs(lv[cur] - lv[parent[cur]])); added1[cur] = i; cur = parent[cur]; } for (ai3 sth : cur_q[i]) { ans[sth[2]] = getans(sth[0]) + sum[sth[0]]; } cur_q[i].clear(); } for (pii sth : updates) { upd(sth.f, -sth.s); } updates.clear(); for (int x : vert) g[x].clear(); solve(l, mid, quel); solve(mid + 1, r, quer); } signed main() { std::ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m>>q; for (int i = 1; i <= n - 1; i++) { int a, b; cin>>a>>b; v[a].pb(b); v[b].pb(a); } dfs(1, 0); for (int i = 1; i <= m; i++) { cin>>a[i]; } vector < ai3 > queries; for (int i = 1; i <= q; i++) { int l, r; cin>>l>>r; if (l == r) ans[i] = 0; else queries.pb({l, r, i}); } solve(1, m, queries); for (int i = 1; i <= q; i++) { cout<<ans[i] + 1<<"\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...