#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
#define ff first
#define ss second
#define pb push_back
// global
const int mxN = 1e5 + 1;
int c[mxN];
vector<int> adj[mxN];
pii range[mxN];
pii range2[mxN];
int depth[mxN];
pii lcasp[mxN * 2][20];
map<pii, int> rangeconv;
int tt = 0, tt2 = 0;
int n, m, q;
void DFSInit(int u = 1, int par = -1, int dep = 0) {
range[u].ff = ++tt;
lcasp[++tt2][0] = {dep, u};
range2[u] = {tt2, tt2};
depth[u] = dep;
for (int &v : adj[u]) {
if (v != par) {
DFSInit(v, u, dep + 1);
lcasp[++tt2][0] = {dep, u};
range2[u].ss = tt2;
}
}
range[u].ss = tt;
rangeconv[range[u]] = u;
}
void InitSparse() {
for (int dep = 1; dep < 20; dep++) {
for (int i = 1; i + (1 << dep) - 1 <= tt2; i++) {
if (lcasp[i][dep - 1].ff < lcasp[i + (1 << (dep - 1))][dep - 1].ff) {
lcasp[i][dep] = lcasp[i][dep - 1];
} else {
lcasp[i][dep] = lcasp[i + (1 << (dep - 1))][dep - 1];
}
}
}
}
int fastlog(int x) {
return (x == 0 ? -1 : 64 - __builtin_clzll(x) - 1);
}
int QueryLCA(int lhs, int rhs) {
// cerr << "QUERY LCA " << lhs << ' ' << rhs << endl;
int bit = fastlog(rhs - lhs + 1);
pii resl = lcasp[lhs][bit], resr = lcasp[rhs - (1 << bit) + 1][bit];
if (resl.ff < resr.ff) return resl.ss;
else return resr.ss;
}
int dir[mxN];
int freq[mxN];
int indeg[mxN];
bool vis[mxN];
int ans;
int lca;
multiset<int> lefts;
multiset<int, greater<int>> rights;
int BuildTree(int u = 1, int par = -1) {
vector<int> res;
for (int &v : adj[u]) {
if (v != par) {
int ret = BuildTree(v, u);
if (ret != -1) {
res.pb(ret);
}
}
}
if (res.size() >= 2 || freq[u]) {
for (int &v : res) {
dir[v] = u;
indeg[u]++;
ans += (depth[v] - depth[u]);
}
lefts.insert(range2[u].ff);
rights.insert(range2[u].ss);
lca = u;
return u;
} else if (res.size() == 1) {
return res.front();
} else {
return -1;
}
}
int find(int u) {
return dir[u];
if (indeg[u]) return u;
return (dir[u] = find(dir[u]));
}
void SubtractNode(int u) {
// cerr << "SUBTRACTING " << u << endl;
freq[u]--;
if (freq[u]) return;
if (!indeg[u]) {
// no children
ans -= (depth[u] - depth[find(u)]);
indeg[find(u)]--;
vis[u] = true;
lefts.erase(lefts.find(range2[u].ff));
rights.erase(rights.find(range2[u].ss));
}
// cerr << u << ": " << find(u) << endl;
while (!freq[u] && !indeg[u]) {
if (!vis[u]) {
vis[u] = true;
lefts.erase(lefts.find(range2[u].ff));
rights.erase(rights.find(range2[u].ss));
}
u = dir[u];
}
int newlca = QueryLCA(*lefts.begin(), *rights.begin());
while (!vis[newlca] && !freq[newlca] && indeg[newlca] == 1) {
vis[newlca] = true;
lefts.erase(lefts.find(range2[newlca].ff));
rights.erase(rights.find(range2[newlca].ss));
newlca = QueryLCA(*lefts.begin(), *rights.begin());
}
ans -= (depth[newlca] - depth[lca]);
lca = newlca;
}
int SubtractRange(int l, int r) {
// cerr << "SUBTRACTING RANGE " << l << ' ' << r << endl;
// cerr << ans << endl;
// for (int i = 1; i <= n; i++) {
// cerr << dir[i] << ' ';
// }
// cerr << endl;
// for (int i = 1; i <= n; i++) {
// cerr << indeg[i] << ' ';
// }
// cerr << endl;
// cerr << "LEFT "; for (int x : lefts) cerr << x << ' '; cerr << endl;
// cerr << "RIGHT "; for (int x : rights) cerr << x << ' '; cerr << endl;
if (l > r) return ans;
int nans = ans;
queue<int> q;
vector<pii> track;
vector<int> track2;
for (int i = l; i <= r; i++) {
freq[c[i]]--;
if (!freq[c[i]]) {
if (!freq[c[i]] && !indeg[c[i]]) {
q.push(c[i]);
track2.pb(c[i]);
vis[c[i]] = true;
lefts.erase(lefts.find(range2[c[i]].ff));
rights.erase(rights.find(range2[c[i]].ss));
}
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
// cerr << u << ' ' << dir[u] << endl;
nans -= (depth[u] - depth[dir[u]]);
indeg[dir[u]]--;
track.pb({dir[u], -1});
if (!freq[dir[u]] && !indeg[dir[u]]) {
q.push(dir[u]);
if (!vis[dir[u]]) {
track2.pb(dir[u]);
lefts.erase(lefts.find(range2[dir[u]].ff));
rights.erase(rights.find(range2[dir[u]].ss));
}
}
}
// cerr << "LEFT "; for (int x : lefts) cerr << x << ' '; cerr << endl;
// cerr << "RIGHT "; for (int x : rights) cerr << x << ' '; cerr << endl;
int newlca = QueryLCA(*lefts.begin(), *rights.begin());
while (!vis[newlca] && !freq[newlca] && indeg[newlca] == 1) {
track2.pb(newlca);
vis[newlca] = true;
lefts.erase(lefts.find(range2[newlca].ff));
rights.erase(rights.find(range2[newlca].ss));
newlca = QueryLCA(*lefts.begin(), *rights.begin());
}
// cerr << lca << ' ' << newlca << endl;
nans -= (depth[newlca] - depth[lca]);
for (int i = l; i <= r; i++) {
freq[c[i]]++;
}
for (pii &u : track) {
indeg[u.ff] -= u.ss;
}
for (int &u : track2) {
lefts.insert(range2[u].ff);
rights.insert(range2[u].ss);
vis[u] = false;
}
return nans;
}
void init() {
// init
}
const int BLOCK = 1000;
bool cmp(pair<pii, int> &lhs, pair<pii, int> &rhs) {
if ((lhs.ff.ff - 1) / BLOCK != (rhs.ff.ff - 1) / BLOCK) {
return ((lhs.ff.ff - 1) / BLOCK) < ((rhs.ff.ff - 1) / BLOCK);
}
return lhs.ff.ss > rhs.ff.ss;
}
void solve() {
// solve
cin >> n >> m >> q;
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
DFSInit();
InitSparse();
for (int i = 1; i <= m; i++) cin >> c[i];
pair<pii, int> queries[q];
int fin[q];
for (int i = 0; i < q; i++) {
cin >> queries[i].ff.ff >> queries[i].ff.ss;
queries[i].ss = i;
}
sort(queries, queries + q, cmp);
int ptr = 0;
for (int st = 1; st <= m; st += BLOCK) {
for (int i = 1; i <= n; i++) {
indeg[i] = 0;
dir[i] = 0;
freq[i] = 0;
vis[i] = false;
}
lefts.clear(); rights.clear();
ans = 1;
for (int i = st; i <= m; i++) {
freq[c[i]]++;
}
BuildTree();
int curptr = m;
while (ptr < q && queries[ptr].ff.ff <= st + BLOCK - 1) {
while (curptr > queries[ptr].ff.ss) {
SubtractNode(c[curptr]);
curptr--;
}
fin[queries[ptr].ss] = SubtractRange(st, queries[ptr].ff.ff - 1);
ptr++;
}
}
for (int i = 0; i < q; i++) {
cout << fin[i] << endl;
}
// for (int curquery = 1; curquery <= q; curquery++) {
// int l, r;
// cin >> l >> r;
// if (l == r) {
// cout << "1\n";
// continue;
// }
// // cerr << "QUERY " << l << ' ' << r << endl;
// for (int i = 1; i <= n; i++) {
// indeg[i] = 0;
// dir[i] = 0;
// freq[i] = 0;
// vis[i] = false;
// }
// lefts.clear(); rights.clear();
// ans = 1;
// for (int i = 1; i <= r; i++) {
// freq[c[i]]++;
// }
// BuildTree();
// // cerr << ans << endl;
// // for (int i = 1; i <= n; i++) {
// // cerr << dir[i] << ' ';
// // }
// // cerr << endl;
// // for (int i = 1; i <= n; i++) {
// // cerr << indeg[i] << ' ';
// // }
// // cerr << endl;
// // cerr << "LEFT "; for (int x : lefts) cerr << x << ' '; cerr << endl;
// // cerr << "RIGHT "; for (int x : rights) cerr << x << ' '; cerr << endl;
// cout << SubtractRange(1, l - 1) << endl;
// }
}
int32_t main() {
ios::sync_with_stdio(0); cin.tie(0);
init(); solve();
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
2 |
Correct |
2 ms |
2644 KB |
Output is correct |
3 |
Correct |
2 ms |
2692 KB |
Output is correct |
4 |
Incorrect |
4 ms |
2688 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
2 |
Correct |
2 ms |
2644 KB |
Output is correct |
3 |
Correct |
2 ms |
2692 KB |
Output is correct |
4 |
Incorrect |
4 ms |
2688 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2692 KB |
Output is correct |
2 |
Correct |
2 ms |
2644 KB |
Output is correct |
3 |
Correct |
10 ms |
2772 KB |
Output is correct |
4 |
Incorrect |
2095 ms |
42104 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
2 |
Incorrect |
2445 ms |
31636 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
2 |
Correct |
2 ms |
2688 KB |
Output is correct |
3 |
Correct |
11 ms |
2772 KB |
Output is correct |
4 |
Execution timed out |
5031 ms |
36020 KB |
Time limit exceeded |
5 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2644 KB |
Output is correct |
2 |
Correct |
2 ms |
2644 KB |
Output is correct |
3 |
Correct |
2 ms |
2692 KB |
Output is correct |
4 |
Incorrect |
4 ms |
2688 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |