Title Link: https://cn.vjudge.net/problem/HDU-5709
Given an n-point tree, each node has a color. How many kinds of colors are there in the subtree of a point that is not more than d away from this point
Explanation:
Build two line segment trees for each node
t1[x] maintains the number of colors within [l,r] in the subtree of X. the same color is only calculated once, and the one with the lowest depth is taken
t2[x] maintains the minimum depth of each color in the subtree of X
Merge from the bottom to the top. t1 merges directly first. When t2 merges, if the same color appears, the one with the smaller depth will be reserved, and the one with the larger depth in t1 will be deleted. When querying, sum directly in the corresponding t1. As for the complexity, O((n+m)logn) is used. It feels that the constant should be very large. As for how big the memory is, let's look at the restrictions. Look at the others who are big Most of them are about 1e7, mainly to see that the n is about 1e5, which gives a lot of time. Just try it.
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m; int t1[N],t2[N]; int f[N],c[N],d[N]; int rson[N*110],lson[N*110],val[N*110]; int tot; int newnode() { tot++; lson[tot]=0; rson[tot]=0; val[tot]=0; return tot; } int update(int pre,int l,int r,int pos,int v) { int cur=newnode(); val[cur]=val[pre]+v; lson[cur]=lson[pre]; rson[cur]=rson[pre]; if(l==r)return cur; int mid=(l+r)>>1; if(pos<=mid) lson[cur]=update(lson[pre],l,mid,pos,v); else rson[cur]=update(rson[pre],mid+1,r,pos,v); return cur; } int merge1(int x,int y,int l,int r) { if(!x || !y) return x + y; int cur=newnode(); val[cur]=val[x]+val[y]; if(l==r)return cur; int mid=(r+l)>>1; lson[cur]=merge1(lson[x],lson[y],l,mid); rson[cur]=merge1(rson[x],rson[y],mid+1,r); return cur; } int merge2(int x,int y,int l,int r,int u) { if(!x || !y) return x + y; int cur=newnode(); if(l==r) { val[cur]=min(val[x],val[y]); if(val[x]<val[y])t1[u]=update(t1[u],1,n,val[y],-1); else t1[u]=update(t1[u],1,n,val[x],-1); return cur; } int mid=(r+l)>>1; lson[cur]=merge2(lson[x],lson[y],l,mid,u); rson[cur]=merge2(rson[x],rson[y],mid+1,r,u); return cur; } int query(int p,int l,int r,int rt) { if(rt==0)return 0; if(r<=p) return val[rt]; int mid=(r+l)>>1; int res=0; res+=query(p,l,mid,lson[rt]); if(p>mid) res+=query(p,mid+1,r,rson[rt]); return res; } int main() { int T,nn=1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); tot=0; for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(int i=2;i<=n;i++)scanf("%d",&f[i]); for(int i=1;i<=n;i++) d[i]=d[f[i]]+1; for(int i=1;i<=n;i++) { t1[i]=update(0,1,n,d[i],1); t2[i]=update(0,1,n,c[i],d[i]); } for(int i=n;i>1;i--) { t1[f[i]]=merge1(t1[f[i]],t1[i],1,n); t2[f[i]]=merge2(t2[f[i]],t2[i],1,n,f[i]); } int ans=0; int u,dep; while(m--) { scanf("%d%d",&u,&dep); // cout<<ans<<"==\n"; u^=ans; dep^=ans; printf("%d\n",ans=query(min(d[u]+dep,n),1,n,t1[u])); } } return 0; }