#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int NMAX = 2e5;
const int RMAX = 25000;
const int BLOCK = 160;
struct AIB {
int n;
int aib[NMAX + 1];
void init(int n) {
this->n = n;
fill(aib + 1, aib + n + 1, 0);
}
void update(int pos, int value) {
for(int i = pos; i <= n; i += i & (-i)) {
aib[i] += value;
}
}
int query(int pos) {
int answer = 0;
for(int i = pos; i >= 1; i -= i & (-i)) {
answer += aib[i];
}
return answer;
}
}aib;
int n, r, q, t;
int reg[NMAX + 1];
int freq[RMAX + 1];
int in[NMAX + 1], out[NMAX + 1];
vector<int> g[NMAX + 1], in_reg[RMAX + 1], nodes_reg[RMAX + 1];
void DFS(int node, int dad = 0) {
in[node] = ++t;
in_reg[reg[node]].push_back(in[node]);
for(int next_node : g[node]) {
if(next_node != dad) {
DFS(next_node, node);
}
}
out[node] = t;
}
int query_small(int r1, int r2) {
int answer = 0;
for(int node : nodes_reg[r1]) {
auto itr = upper_bound(in_reg[r2].begin(), in_reg[r2].end(), out[node]);
auto itl = lower_bound(in_reg[r2].begin(), in_reg[r2].end(), in[node]);
answer += itr - itl;
}
return answer;
}
int query_big(int r1, int r2) {
/// Activate r2
/// Query r1
aib.init(n);
for(int node : nodes_reg[r2]) {
aib.update(in[node], 1);
}
int answer = 0;
for(int node : nodes_reg[r1]) {
answer += aib.query(out[node]) - aib.query(in[node] - 1);
}
return answer;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> r >> q;
cin >> reg[1];
for(int i = 2; i <= n; i++) {
int x;
cin >> x >> reg[i];
g[x].push_back(i);
g[i].push_back(x);
}
for(int i = 1; i <= n; i++) {
nodes_reg[reg[i]].push_back(i);
freq[reg[i]]++;
}
DFS(1);
while(q--) {
int r1, r2;
cin >> r1 >> r2;
if(freq[r1] <= BLOCK) {
cout << query_small(r1, r2) << endl;
}
else {
cout << query_big(r1, r2) << endl;
}
}
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |