URL: https://scut.online/p/106
Meaning of the questions:
Given a point right at $ 1 $ tree is a root node, the tree has the right Qiuzi several nodes is smaller than or equal $ k $.
answer:
President version tree, tree to determine timestamp $ $ DFS enter a first node, and while processing the sub-tree nodes, and the time stamp obtained $ $ DFS in order for a node length the size of the sub-tree nodes $ -1 $ sequence is the subtree corresponding to this node, the number of requirements to the Chairman tree. The principle is similar request interval k-th largest, each of them just before the President tree are stored sequence $ m (1 \ leq m \ leq n) $ size is the number of the total number $ [1, n] $ number, then the number of queries to the interval $ [1, k] $ of the number of inquiries. Since this value is too large problem, because the weights are discretized, the input of $ k $ have discrete, find the first number is less than equal to k.
AC Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=100005; struct cheiftree { struct node { int l,r,sum; }; node tr[MAXN*20]; int rt[MAXN]; int cnt=0; void init() { cnt=0; } void build(int &rt,int l,int r) { rt=++cnt; tr[rt].sum=0; int m=(l+r)/2; if(l==r) return; build(tr[rt].l,l,m); build(tr[rt].r,m+1,r); } void update(int &rt,int l,int r,int k) { tr[++cnt]=tr[rt]; rt=cnt; ++tr[rt].sum; if(l==r) return; int m=(l+r)/2; if(k<=m) update(tr[rt].l,l,m,k); else update(tr[rt].r,m+1,r,k); } int query(int rl,int rr,int l,int r,int val) { if(l==r) return tr[rr].sum-tr[rl].sum; int m=(l+r)/2; if(val<=m) return query(tr[rl].l,tr[rr].l,l,m,val); else if(val>m) return tr[tr[rr].l].sum-tr[tr[rl].l].sum+query(tr[rl].r,tr[rr].r,m+1,r,val); } }; cheiftree tr; int in[MAXN],a[MAXN],b[MAXN],size[MAXN],vis[MAXN]; int cnt=0; vector<int>E[MAXN]; void print() { for(int i=1;i<=tr.cnt;++i) cout<<tr.tr[i].l<<" "<<tr.tr[i].r<<" "<<tr.tr[i].sum<<endl; } void dfs(int u) { in[u]=++cnt; size[u]=1; vis[cnt]=u; for(auto &i:E[u]) { dfs(i); size[u]+=size[i]; } } void init(int n) { cnt=0; for(int i=1;i<=n;++i) E[i].clear(); } int main() { int n,t,m; while(~scanf("%d%d",&n,&m)) { init(n); for(int i=1;i<n;++i) { scanf("%d",&t); E[t].push_back(i+1); } dfs(1); //for(int i=1;i<=cnt;++i) //cout<<in[i]<<" "<<size[i]<<" "<<vis[i]<<endl; for(int i=1;i<=n;++i) { scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+1+n); int nnew=unique(b+1,b+1+n)-b-1; tr.init(); tr.build(tr.rt[0],1,nnew); for(int i=1;i<=n;++i) { tr.rt[i]=tr.rt[i-1]; int pos=lower_bound(b+1,b+1+nnew,a[vis[i]])-b; tr.update(tr.rt[i],1,nnew,pos); } //print(); for(int i=0;i<m;++i) { scanf("%d%d",&n,&t); int k=upper_bound(b+1,b+1+nnew,t)-b-1; int l=tr.rt[in[n]-1],r=tr.rt[in[n]+size[n]-1]; printf("%d\n",tr.query(l,r,1,nnew,k)); } } return 0; }