This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using ll = long long;
#define pll pair <ll,ll>
#define fi first
#define se second
#define sz(a) (ll((a).size()))
#define BIT(mask,i) (((mask) >> (i))&1)
#define MASK(i) (1LL << (i))
#define MP make_pair
using namespace std;
const ll bl_size = 300;
ll n,m,q;
const ll MAXN = 1e5;
const ll MAXK = 17;
ll c[MAXN+100];
struct query{
ll l,r,id;
};
query all[MAXN+100];
ll ans[MAXN+100];
vector <ll> g[MAXN+100];
ll in[MAXN+100],out[MAXN+100];
ll timeDFS;
ll depth[MAXN+100];
ll sp[MAXK][MAXN+100];
bool anc(ll x,ll y){
return in[x] <= in[y] && in[y] <= out[x];
}
ll lca(ll x,ll y){
for (ll j = MAXK - 1;j >= 0;j --){
if (!anc(sp[j][x],y))x = sp[j][x];
}
if (!anc(x,y))x=sp[0][x];
return x;
}
void dfs(ll u,ll p){
in[u] = ++timeDFS;
sp[0][u] = p;
depth[u] = depth[p] + 1;
for (auto v:g[u]){
if (v==p)continue;
dfs(v,u);
}
out[u] = timeDFS;
}
int main(){
ios_base::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
cin>>n>>m>>q;
for (ll i = 1;i < n;i ++){
ll u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,1);
for (ll j = 1;j < MAXK;j ++){
for (ll i = 1;i <= n;i ++){
sp[j][i] = sp[j-1][sp[j-1][i]];
}
}
for (ll i = 1;i <= m;i ++)cin>>c[i];
for (ll i = 1;i <= q;i ++){
cin>>all[i].l>>all[i].r;
all[i].id = i;
}
sort(all+1,all+1+q,[](query x,query y){
x.l /= bl_size;
y.l /= bl_size;
if (x.l != y.l)return x.l<y.l;
else{
if ((x.l)&1)return x.r < y.r;
else return x.r > y.r;
}
});
ll cur_l = 1,cur_r = 1;
multiset <pll> tree({MP(in[c[1]],c[1])});
ll res = 1;
auto eval = [&](ll x) -> ll{
//evaluate if insert x
ll root = lca((*tree.begin()).se,(*tree.rbegin()).se);
if (anc(root,x)){
auto nxt = tree.lower_bound(MP(in[x],x));
if (nxt == tree.end()){
nxt = prev(nxt);
}
if (anc(x,(*nxt).se))return 0;
else {
ll lca1 = lca(x,(*nxt).se);
ll lca2 = 1;
if (nxt != tree.begin())lca2 = lca(x,(*prev(nxt)).se);
if (depth[lca2] > depth[lca1])lca1 = lca2;
return depth[x] - depth[lca1];
}
}
else{
return depth[x] + depth[root] - 2 * depth[lca(root,x)];
}
};
auto add = [&](ll x){
res += eval(x);
tree.insert(MP(in[x],x));
};
auto del = [&](ll x){
tree.erase(tree.find(MP(in[x],x)));
res -= eval(x);
};
for (ll i = 1;i <= q;i ++){
ll l = all[i].l,r = all[i].r;
while (cur_r < r){
cur_r++;
add(c[cur_r]);
//add cur_r
}
while (cur_l > l){
cur_l--;
add(c[cur_l]);
//add cur_l
}
while (cur_r > r){
//
del(c[cur_r]);
cur_r--;
}
while (cur_l < l){
//
del(c[cur_l]);
cur_l++;
}
ans[all[i].id] = res;
}
for (ll i = 1;i <= q;i ++)cout<<ans[i]<<'\n';
// cout<<'\n';
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |