#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
#define vec vector
const ll maxn = 2e5 + 1, maxreg = 25001;
const ll block = sqrt(maxn);
vec<ll> gr[maxn];
ll track[maxn], regionof[maxn], sizes[maxn], tin[maxn], tout[maxn];
unordered_map<ll, unordered_map<ll, ll> > precalc;
vec<ll> entryTimes[maxreg];
vec<ll> setOfRegion[maxreg];
ll timer = 0;
void dfs(ll v, ll par, ll reg)
{
precalc[reg][regionof[v]] += track[reg];
track[regionof[v]]++;
for (auto &e : gr[v])
if (e != par)
dfs(e, v, reg);
track[regionof[v]]--;
}
void dfs1(ll v, ll par = -1)
{
tin[v] = ++timer;
entryTimes[regionof[v]].push_back(tin[v]);
for (auto &e : gr[v])
if (e != par)
dfs1(e, v);
tout[v] = timer;
}
int main()
{
ll n, r, q;
cin >> n >> r >> q;
ll i;
ll reg, belongs;
cin >> reg;
sizes[reg]++;
setOfRegion[reg].push_back(1);
regionof[1] = reg;
for (i = 2; i <= n; i++)
{
cin >> belongs >> reg;
regionof[i] = reg;
gr[belongs].push_back(i);
setOfRegion[reg].push_back(i);
sizes[reg]++;
}
dfs1(1);
for (i = 1; i <= r; i++)
if (sizes[i] >= block)
dfs(1, -1, i);
while (q--)
{
ll parent, child;
cin >> parent >> child;
if (sizes[parent] >= block)
cout << precalc[parent][child] << endl;
else
{
ll res = 0;
for (auto &el : setOfRegion[parent])
res += upper_bound(entryTimes[child].begin(), entryTimes[child].end(), tout[el]) - lower_bound(entryTimes[child].begin(), entryTimes[child].end(), tin[el]);
cout << res << endl;
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |