#include<iostream>
#include<stack>
#include<map>
#include<vector>
#include<string>
#include<unordered_map>
#include <queue>
#include<cstring>
#include<limits.h>
#include <cassert>
#include<cmath>
#include<set>
#include<algorithm>
#include <iomanip>
#include<numeric> //gcd(a,b)
#include<bitset>
#include <cstdlib>
#include <cstdint>
using namespace std;
#define ll long long
#define f first
//#define endl "\n"
#define s second
#define pii pair<int,int>
#define ppii pair<int,pii>
#define vi vector<int>
#define pb push_back
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define F(n) for(int i=0;i<n;i++)
#define lb lower_bound
#define ub upper_bound
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);
#pragma GCC optimize ("03,unroll-loops")
using namespace std;
//#define int long long
//#define double long double
const int mod=1e9+7,mxn=2e5+5,lg=60,inf=1e9,minf=-1e9,mx=3e4;
int root=700,st;
vector<int>adj[mxn+10];
int re[mxn+10],recnt[mxn+10],sz[mxn+10],hvyp[mxn+10],up[mxn+10];
int tin[mxn+10],tout[mxn+10],T=0;
void getsz(int cur){sz[cur]=1;for(auto i:adj[cur])getsz(i),sz[cur]+=sz[i];}
void dfs(int cur,int hvypa){
tin[cur]=++T;
int hvy=0;
hvyp[cur]=hvypa;
for(auto i:adj[cur]){
if(sz[i]>sz[hvy])hvy=i;
up[i]=cur;
}
for(auto i:adj[cur])if(i!=hvy)dfs(i,i);
if(hvy)dfs(hvy,hvypa);
tout[cur]=T;
}
bool cmp(int a,int b){return tin[a]<tin[b];}
struct chain{
vector<int>have,com;
vector<vector<int>>pos;
void init(){
if(have.empty())return;
for(auto i:have)com.pb(re[i]);
sort(all(com));
sort(all(have),cmp);
com.erase(unique(all(com)),com.end());
pos.resize(com.size());
for(auto i:have)pos[lb(all(com),re[i])-com.begin()].pb(tin[i]);
return;
}
int get(int x,int id){
auto it=lb(all(com),id)-com.begin();
if(it>=pos.size()||com[it]!=id)return 0;
if(pos[it].empty())return 0;
if(pos[it].back()<=x)return pos[it].size();
else return upper_bound(all(pos[it]),x)-pos[it].begin();
}
}t[mxn+10];//parent of hvy chain
vector<int>pos[mxn+10];
vector<int>have[mxn+10];
int pre[mx][500];
int32_t main(){
fastio
int n,r,q;cin>>n>>r>>q;
root=sqrt(n);
for(int i=1;i<=n;i++){
if(i!=1){
int b;cin>>b;
adj[b].pb(i);
}
cin>>re[i];
recnt[re[i]]++;
have[re[i]].pb(i);
}
getsz(1);
dfs(1,1);
for(int i=1;i<=n;i++)t[hvyp[i]].have.pb(i);
for(int i=1;i<=n;i++)t[i].init(),pos[re[i]].pb(tin[i]);
for(int i=1;i<=r;i++)sort(all(pos[i]));
vector<int>k;
for(int i=1;i<=r;i++){
if(recnt[i]<root)continue;
k.pb(i);
}
for(int i=1;i<=n;i++){
int cur=i;
while(hvyp[cur]!=1){
for(int j=0;j<k.size();j++){
pre[re[i]][j]+=t[hvyp[cur]].get(tin[cur],k[j]);
}
cur=up[hvyp[cur]];
}
for(int j=0;j<k.size();j++)pre[re[i]][j]+=t[hvyp[cur]].get(tin[cur],k[j]);
}
//qry r1,r2 cout<<pre[r2][pos r1];
while(q--){
int a,b;cin>>a>>b;
if(recnt[a]<root){
int ans=0;
for(auto j:have[a]){
int l=lb(all(pos[b]),tin[j])-pos[b].begin();
if(l==pos[b].size())continue;
int r=ub(all(pos[b]),tout[j])-pos[b].begin()-1;
ans+=(r-l+1);
}
cout<<ans<<endl;
}
else{
auto it=lb(all(k),a)-k.begin();
cout<<pre[b][it]<<endl;
}
}
}
/*
sqrt decomp
if region cnt<=sqrtn -> burte force sqrtn{
do euler tour keep vector of pos in euler tour for each region
when qry r1,r2 loop through all sqrtn node then qry in subtree of that node
qry-> bs l,r in vector of r2; ans+=(r-l+1)
}
else we precompute the region to other region (keep sqrtn(r)){
use merge sort tree +hld? (too costly?){
dont need merge sort?
keep chain then each chain keep vector of pos for each region
}
}
*/
Compilation message
regions.cpp: In member function 'int chain::get(int, int)':
regions.cpp:72:8: warning: comparison of integer expressions of different signedness: 'long int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
72 | if(it>=pos.size()||com[it]!=id)return 0;
| ~~^~~~~~~~~~~~
regions.cpp: In function 'int32_t main()':
regions.cpp:107:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
107 | for(int j=0;j<k.size();j++){
| ~^~~~~~~~~
regions.cpp:112:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
112 | for(int j=0;j<k.size();j++)pre[re[i]][j]+=t[hvyp[cur]].get(tin[cur],k[j]);
| ~^~~~~~~~~
regions.cpp:121:9: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
121 | if(l==pos[b].size())continue;
| ~^~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
35160 KB |
Output is correct |
2 |
Correct |
8 ms |
35160 KB |
Output is correct |
3 |
Correct |
8 ms |
35160 KB |
Output is correct |
4 |
Correct |
10 ms |
35160 KB |
Output is correct |
5 |
Correct |
12 ms |
35140 KB |
Output is correct |
6 |
Correct |
15 ms |
35160 KB |
Output is correct |
7 |
Correct |
20 ms |
35160 KB |
Output is correct |
8 |
Correct |
25 ms |
35416 KB |
Output is correct |
9 |
Correct |
38 ms |
35672 KB |
Output is correct |
10 |
Correct |
55 ms |
36184 KB |
Output is correct |
11 |
Correct |
80 ms |
36688 KB |
Output is correct |
12 |
Correct |
99 ms |
36996 KB |
Output is correct |
13 |
Correct |
136 ms |
37976 KB |
Output is correct |
14 |
Correct |
222 ms |
40704 KB |
Output is correct |
15 |
Correct |
222 ms |
42308 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1518 ms |
43624 KB |
Output is correct |
2 |
Correct |
1862 ms |
46172 KB |
Output is correct |
3 |
Correct |
2314 ms |
45224 KB |
Output is correct |
4 |
Correct |
186 ms |
38504 KB |
Output is correct |
5 |
Correct |
225 ms |
39252 KB |
Output is correct |
6 |
Correct |
547 ms |
55668 KB |
Output is correct |
7 |
Correct |
1055 ms |
63904 KB |
Output is correct |
8 |
Correct |
1070 ms |
67204 KB |
Output is correct |
9 |
Correct |
1855 ms |
51340 KB |
Output is correct |
10 |
Correct |
2836 ms |
103500 KB |
Output is correct |
11 |
Correct |
3858 ms |
59940 KB |
Output is correct |
12 |
Correct |
1166 ms |
87160 KB |
Output is correct |
13 |
Correct |
1510 ms |
87772 KB |
Output is correct |
14 |
Correct |
1953 ms |
95840 KB |
Output is correct |
15 |
Correct |
2506 ms |
104796 KB |
Output is correct |
16 |
Correct |
2284 ms |
109220 KB |
Output is correct |
17 |
Correct |
2349 ms |
98104 KB |
Output is correct |