Union on Tree

Read problems statements in Mandarin Chinese  and Russian.
There is a country whose road system is a tree, the nodes in the tree represent cities and the edge is the road between them, and each edge is of unit length. For safety, the government should put guards to protect all cities. But the government is in shortage of money. So they might not be able to protect all cites.
You're concerned about the country's safety, so you get the information of the guards. And you know that on the i-th day, there are k[i] guards on the road system, and j-th guard is on node a[j] and can protect every node whose distance to a[j] is not larger than r[j]. And you want to know how many nodes in the road system is protected by at least one guard.
Input
The first line contains an integer n, denoting the number of the cities.
Then n-1 lines follows, each line contains 2 integers a and b, denoting there is an edge between city a and b (1-based index).
The next line contains an integer Q, denoting the number of the days.
Then Q lines's description follows, each contains an integer k, denoting the number of guards in that day, and k integer pairs a[i],r[i] denoting the guards's information, for simplicity, no node will have more than 1 guard.
Constraints

 1 ≤ n, Q ≤ 50000. 
 The total number of guards in the queries ≤ 500000. 

Output
For each day, output the answer in one line.
Example
Input:
20
1 2
1 3
1 4
4 5
4 6
2 7
4 8
5 9
7 10
2 11
9 12
8 13
1 14
12 15
9 16
7 17
12 18
1 19
6 20
5
2 9 3 12 5 
3 3 3 4 1 11 5 
3 3 3 10 4 19 2 
2 3 4 10 2 
5 5 4 11 2 16 2 18 1 19 2
Output:
16
16
13
16
18

Example input:

Example output:


Solution:

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    #define	n	100005
    #define For(i,a,b)	for(int i=a,lim=b;i<=lim;i++)
    #define Rep(i,a,b)	for(int i=a,lim=b;i>=lim;i--)
    
    int		N,Q,C,D,st[n],val[n];
    struct	Lin{int v,next;}E[n<<1];
    
    int 	V[n],siz[n],Max[n];
    int 	Dep[n],Dfn[n],F[20][n]; 
    int		A[n],B[n],H[n],P[n],R[n],Len[n];
    
    struct	Nod{int x,d;};
    vector<Nod>G1[n],G2[n];
    
    int		T1[n],T2[n];
    vector<int>C1[n],C2[n];
    
    void	Link(int u,int v){
    		E[++D]=(Lin){v,st[u]};	st[u]=D;
    		E[++D]=(Lin){u,st[v]};	st[v]=D;
    }
    void	DFS1(int u,int f){
    		siz[u]=1;	Max[u]=0;
    		for (int i=st[u],v;i;i=E[i].next)
    			if	(!V[v=E[i].v]&&v!=f)	DFS1(v,u),siz[u]+=siz[v],Max[u]=max(Max[u],siz[v]);
    }
    int		DFS2(int u,int f,int S){
    		int Rt=u;	Max[u]=max(Max[u],S-siz[u]);
    		for (int i=st[u],v;i;i=E[i].next)
    		if	(!V[v=E[i].v]&&v!=f)	{
    			int t=DFS2(v,u,S);
    			if	(Max[t]<Max[Rt])	Rt=t;
    		}	return	Rt;
    }
    
    void	DFS3(int u,int f,int d,int a,int b){
    		for	(;d>T1[a];)	T1[a]++,C1[a].push_back(0);	
    		for	(;d>T2[b];)	T2[b]++,C2[b].push_back(0);	
    
    		G1[u].push_back((Nod){a,d});	C1[a][d]+=val[u];
    		G2[u].push_back((Nod){b,d});	C2[b][d]+=val[u];
    
    		for (int i=st[u],v;i;i=E[i].next)
    			if	(!V[v=E[i].v]&&v!=f)	DFS3(v,u,d+1,a,b);
    }
    void	Work(int u){
    		DFS1(u,0);	V[u=DFS2(u,0,siz[u])]=1;
    
    		T1[u]=-1;
    		for (int i=st[u],v;i;i=E[i].next)
    			if	(!V[v=E[i].v])	T2[++C]=-1,DFS3(v,0,1,u,C);
    		G1[u].push_back((Nod){u,0});
    
    		for (int i=st[u],v;i;i=E[i].next)
    			if	(!V[v=E[i].v])	Work(v);
    }
    int		Query(int u,int d){
    		int ret=0;
    		For(i,0,G1[u].size()-1){
    			int x=G1[u][i].x,k=G1[u][i].d;
    			ret+=(k<=d)*val[x];
    			if	(k<=d&&T1[x]!=-1)	ret+=C1[x][min(T1[x],d-k)];
    		}
    		For(i,0,G2[u].size()-1){
    			int x=G2[u][i].x,k=G2[u][i].d;
    			if	(k<=d&&T2[x]!=-1)	ret-=C2[x][min(T2[x],d-k)];
    		}
    		return	ret;
    }
    
    void	DFS(int u,int f){
    		Dep[u]=Dep[f]+1;	Dfn[u]=++*Dfn;
    		for (int i=st[u],v;i;i=E[i].next)
    			if	((v=E[i].v)!=f)	F[0][v]=u,DFS(v,u);
    }
    int		LCA(int u,int v){
    		if	(Dep[u]>Dep[v])	swap(u,v);
    		Rep(i,16,0)	if	(Dep[F[i][v]]>=Dep[u])	v=F[i][v];
    		if	(u==v)	return	u;
    		Rep(i,16,0)	if	(F[i][u]!=F[i][v])	u=F[i][u],v=F[i][v];
    		return	F[0][u];
    }
    int		Find(int u,int d){
    		Rep(i,16,0)	if	((1<<i)<=d)	u=F[i][u],d-=1<<i;
    		return	u;
    }
    
    #define CH	(ch=getchar())
    int		IN(){
    		int x=0,ch;
    		for	(;CH<'0'||ch>'9';);
    		for	(;ch>='0'&&ch<='9';CH)	(x*=10)+=ch-'0';
    		return	x;
    }
    bool	Cmp(int a,int b)	{return	Dfn[a]<Dfn[b];}
    
    int		main(){
    		N=IN();
    		For(i,2,N)	Link(IN(),N+i),Link(N+i,IN());
    		For(i,1,N)	val[i]=1;	Work(1);
    
    		For(u,1,2*N)For(i,1,T1[u])	C1[u][i]+=C1[u][i-1];
    		For(u,1,C)	For(i,1,T2[u])	C2[u][i]+=C2[u][i-1];
    
    		DFS(1,0);
    		For(i,1,16)	For(j,1,N)	F[i][j]=F[i-1][F[i-1][j]];
    
    		for (Q=IN();Q--;)	{
    			int	T=IN();	*H=0;
    			For(i,1,T)	H[++*H]=A[i]=IN(),B[i]=IN()*2;
    			sort(H+1,H+*H+1,Cmp);
    
    			For(i,2,T)	H[++*H]=LCA(H[i-1],H[i]);	H[++*H]=1;
    			sort(H+1,H+*H+1,Cmp);	*H=unique(H+1,H+*H+1)-H-1;
    			For(i,2,*H)	P[H[i]]=LCA(H[i-1],H[i]);
    
    			For(i,1,*H)	R[H[i]]=-1;
    			For(i,1,T)	R[A[i]]=B[i];
    			For(i,2,*H)	Len[H[i]]=Dep[H[i]]-Dep[P[H[i]]];
    
    			Rep(i,*H,2)	R[P[H[i]]]=max(R[P[H[i]]],R[H[i]]-Len[H[i]]);
    			For(i,2,*H)	R[H[i]]=max(R[H[i]],R[P[H[i]]]-Len[H[i]]);
    
    			int Ans=0;
    			For(i,1,*H)	if	(R[H[i]]>=0)Ans+=Query(H[i],R[H[i]]);
    			For(i,2,*H)	{
    				int u=H[i],v=P[H[i]],r=Dep[u]-Dep[v];
    				if	(R[u]!=-1&&R[v]!=-1&&R[u]+R[v]-r>=0)	{
    					int d=(R[u]+R[v]-r)/2,x=Find(u,R[u]-d);	Ans-=Query(x,d);
    				}
    			}
    			printf("%d\n",Ans);
    		}
    }