考虑整体二分,问题就变成了每个(水果)路径有多少个满足条件(权值)的(盘子)子路径
考虑一个盘子(a,b)表示两端点(不妨设dfn[a]<dfn[b]),那么他能接到的水果(u,v)一定满足(不妨设dfn[u]<dfn[v]):
1.如果a是b的祖先,则u在(a的在(b,a)链上的孩子)这个子树外,v在b子树内
2.否则,u在a的子树内,v在b的子树内
那么把一个水果(a,b)看成是一个二维点(dfn[a],dfn[b]),对于每个盘子,就是做一个二维区间+1
差分以后变成一个二维数点问题,可以先按x排序,y用树状数组来解决
复杂度$O(nlog^2n)$
然而我写的常数过大哪都卡不过去
#include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pa;
const int maxn=4e4+,maxp=1e7+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,P,Q;
int eg[maxn*][],egh[maxn],ect;
int dfn[maxn][],tot;
int rt[maxn],fa[maxn][],dep[maxn];
int tr[maxn]; inline int lowbit(int x){return x&(-x);} inline void add(int x,int d){
for(;x&&x<=N;x+=lowbit(x)) tr[x]+=d;
}
inline int query(int x){
int re=;
for(;x;x-=lowbit(x)) re+=tr[x];
return re;
} inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a],egh[a]=ect;
} inline void dfs(int x){
for(int i=;fa[x][i]&&fa[fa[x][i]][i];i++){
fa[x][i+]=fa[fa[x][i]][i];
}
dfn[x][]=++tot;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
fa[b][]=x,dep[b]=dep[x]+;
dfs(b);
}dfn[x][]=tot;
} inline int jump(int x,int d){
for(int i=;d;i++,d>>=){
if(d&) x=fa[x][i];
}return x;
} int ans[maxn],nct;
pa val[maxn];
struct Node{
int a,b,d,v,i;
}op[maxn*],tmp[maxn*]; inline void addnode(int x1,int x2,int y1,int y2,int v,int i){
op[++nct]=(Node){x1,y1,,v,i};
if(x2<N&&y2<N) op[++nct]=(Node){x2+,y2+,,v,i};
if(x2<N) op[++nct]=(Node){x2+,y1,-,v,i};
if(y2<N) op[++nct]=(Node){x1,y2+,-,v,i};
} inline void cover(int a,int b,int v,int i){
if(dfn[a][]>dfn[b][]) swap(a,b);
if(dfn[a][]>=dfn[b][]){
int x=jump(b,dep[b]-dep[a]-);
addnode(,dfn[x][]-,dfn[b][],dfn[b][],v,i);
addnode(dfn[b][],dfn[b][],dfn[x][]+,N,v,i);
}else{
addnode(dfn[a][],dfn[a][],dfn[b][],dfn[b][],v,i);
}
} inline void solve(int l,int r,int ql,int qr){
if(l>r||ql>qr) return;
int m=ql+qr>>;
// printf("~%d %d %d %d %d\n",l,r,ql,qr,val[m]);
int p=l-,q=r+;
for(int i=l;i<=r;i++){
if(op[i].d){
if(MP(op[i].v,op[i].i)<=val[m]){
add(op[i].b,op[i].d);
tmp[++p]=op[i];
}else tmp[--q]=op[i];
}else{
int n=query(op[i].b);
if(n>=op[i].v){
ans[op[i].i]=val[m].first;
tmp[++p]=op[i];
}else if(n<op[i].v){
op[i].v-=n;
tmp[--q]=op[i];
}
} }
for(int i=l;i<=r;i++){
if(op[i].d){
if(MP(op[i].v,op[i].i)<=val[m]){
add(op[i].b,-op[i].d);
}
}
}
for(int i=l;i<=p;i++) op[i]=tmp[i];
for(int i=q;i<=r;i++) op[r-i+q]=tmp[i];
solve(l,p,ql,m-),solve(q,r,m+,qr);
} inline bool cmp(Node a,Node b){return a.a==b.a?a.d!=:a.a<b.a;} int main(){
// freopen("fruit1.in","r",stdin);
// freopen("aa.out","w",stdout);
int i,j,k;
N=rd(),P=rd(),Q=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}
dep[]=;dfs();
for(i=;i<=P;i++){
int a=rd(),b=rd(),c=rd();
val[i]=MP(c,i);
cover(a,b,c,i);
}sort(val+,val+P+);
for(i=;i<=Q;i++){
int a=rd(),b=rd(),c=rd();
if(dfn[a][]>dfn[b][]) swap(a,b);
op[++nct]=(Node){dfn[a][],dfn[b][],,c,i};
}
sort(op+,op+nct+,cmp);
solve(,nct,,P);
for(i=;i<=Q;i++) printf("%d\n",ans[i]);
return ;
}