Submission #1001297

#TimeUsernameProblemLanguageResultExecution timeMemory
1001297LonlyRTourism (JOI23_tourism)C++17
10 / 100
5100 ms31568 KiB
#include<bits/stdc++.h> #define all(x) x.begin(), x.end() #define ii pair<int,int> #define ff first #define ss second #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") using namespace std; const int maxn = 1e5 + 5, bl = sqrt(maxn) ; int n, m, q, cnt, cur; int in[maxn], out[maxn], h[maxn], par[18][maxn], id[maxn], c[maxn], ans[maxn], in_set[maxn]; vector<int> adj[maxn], euler = {0}; int lgs[3*maxn]; int rev_in[maxn]; set<int> s; inline int gilbertOrder(int x, int y, int pow, int rotate) { if (pow == 0) { return 0; } int hpow = 1 << (pow-1); int seg = (x < hpow) ? ( (y < hpow) ? 0 : 3 ) : ( (y < hpow) ? 1 : 2 ); seg = (seg + rotate) & 3; const int rotateDelta[4] = {3, 0, 0, 1}; int nx = x & (x ^ hpow), ny = y & (y ^ hpow); int nrot = (rotate + rotateDelta[seg]) & 3; int subSquareSize = int(1) << (2*pow - 2); int ans = seg * subSquareSize; int add = gilbertOrder(nx, ny, pow-1, nrot); ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1); return ans; } struct Q { int l, r, id; int ord; inline void calcOrder() { ord = gilbertOrder(l, r, 21, 0); } } qr[maxn]; inline bool operator<(const Q &a, const Q &b) { return a.ord < b.ord; } void dfs(int x = 1, int p = 1) { h[x] = h[p] + 1; in[x] = ++cnt; id[x] = euler.size(); euler.push_back(x); for (int i : adj[x]) if (i != p) dfs(i, x), euler.push_back(x); out[x] = cnt; } //inline bool sub(int u, int v) /// u in subtree of v //{ // return in[v] <= in[u] && out[u] <= out[v]; //} // //int lca(int u, int v) //{ // if (h[u] > h[v]) swap(u, v); // if (sub(v, u)) return u; // for (int i = 17; i >= 0; i--) // if (sub(u, par[i][v]) == 0) // v = par[i][v]; // return par[0][v]; //} vector<vector<ii>> st; inline void build() { int sz = euler.size(); int LG = __lg(sz); st = vector<vector<ii>>(LG + 1, vector<ii>(sz, {sz, 0})); for (int i = 1; i < sz; i++) st[0][i] = {h[euler[i]], euler[i]}; for (int j = 1; j <= LG; j++) for (int i = 1; i + (1 << j) - 1 < sz; i++) st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]); } inline int lca(int l, int r) { l = id[l]; r = id[r]; if (l > r) swap(l, r); // assert(r-l+1<=n); int k = lgs[(r - l + 1)]; return min(st[k][l], st[k][r - (1 << k) + 1]).ss; } inline void add(int x) { x = c[x]; in_set[x]++; if (in_set[x] == 1) { cur += h[x]; if (s.size() == 0) return s.insert(in[x]), void(); auto it = s.lower_bound(in[x]); if (it == s.begin()) cur -= h[lca(x, rev_in[*it])]; else if (it == s.end()) cur -= h[lca(x, rev_in[*prev(it)])]; else { auto u = rev_in[*it], v = rev_in[*prev(it)]; cur += h[lca(u, v)]; cur -= h[lca(u, x)]; cur -= h[lca(v, x)]; } } s.insert(in[x]); } inline void del(int x) { x = c[x]; in_set[x]--; if (in_set[x] == 0) { cur -= h[x]; if (s.size() == 1) return s.clear(), void(); auto it = s.lower_bound(in[x]); if (it == s.begin()) cur += h[lca(x, rev_in[*next(it)])]; else if (next(it) == s.end()) cur += h[lca(x, rev_in[*prev(it)])]; else { auto u = rev_in[*prev(it)], v = rev_in[*next(it)]; cur -= h[lca(u, v)]; cur += h[lca(u, x)]; cur += h[lca(v, x)]; } s.erase(it); } } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); //cout.tie(0); // freopen("test.inp", "r", stdin); // freopen("test.out", "w", stdout); cin >> n >> m >> q; for (int i = 1, u, v; i < n; i++) cin >> u >> v, adj[u].push_back(v), adj[v].push_back(u); for (int i = 1; i <= m; i++) cin >> c[i]; dfs(); for (int i = 1; i <= 3*n; i++) lgs[i] = __lg(i); build(); for (int i = 1; i <= n; i++) rev_in[in[i]] = i; for (int i = 1; i <= q; i++) cin >> qr[i].l >> qr[i].r, qr[i].id = i, qr[i].calcOrder(); sort(qr + 1, qr + q + 1); for (int i = 1, l = 1, r = 0; i <= q; i++) { auto [lx, rx, id, tmp] = qr[i]; while (r < rx) add(++r); while (l > lx) add(--l); while (r > rx) del(r--); while (l < lx) del(l++); ans[id] = cur - h[lca(rev_in[*s.begin()], rev_in[*s.rbegin()])] + 1; } for (int i = 1; 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...