网上一堆题解这里不再赘述
奈何我连扫描线都写不动只好上kdtree了
#include<cstdio>
#include<cmath>
#include<algorithm>
#define gm 40001
int n,p,q;
int cmp;
struct pnt
{
int p[2];
pnt():p(){}
pnt(int x,int y){p[0]=x,p[1]=y;}
int& operator[] (size_t x) {return p[x];}
const int& operator[] (size_t x) const {return p[x];}
bool operator< (const pnt &b) const{return p[cmp]<b[cmp];}
};
inline void min(int &a,int b){b<a?a=b:0;}
inline void max(int &a,int b){a<b?a=b:0;}
inline void min(pnt &a,const pnt &b){min(a[0],b[0]),min(a[1],b[1]);}
inline void max(pnt &a,const pnt &b){max(a[0],b[0]),max(a[1],b[1]);}
struct pan
{
pnt ap,bp;
int val;
operator int() const {return val;}
bool inner(const pnt &mn,const pnt &mx) const
{
return ap[0]<=mn[0]&&ap[1]<=mn[1]&&bp[0]>=mx[0]&&bp[1]>=mx[1];
}
bool outer(const pnt &mn,const pnt &mx) const
{
return ap[0]>mx[0]||ap[1]>mx[1]||bp[0]<mn[0]||bp[1]<mn[1];
}
}pst[gm<<1];
int tot=0;
struct node
{
node *l,*r;
pnt p,mn,mx;
int cnt,kis,mark;
int *ptr;
node(const pnt &p,int cnt,int *ptr):l(),r(),p(p),mn(p),mx(p),cnt(cnt),kis(),mark(),ptr(ptr){}
void up()
{
kis=cnt;
if(l&&l->kis>0&&(kis<=0||l->kis<kis)) kis=l->kis;
if(r&&r->kis>0&&(kis<=0||r->kis<kis)) kis=r->kis;
}
void set(int x)
{
cnt-=x; kis-=x;
mark+=x;
}
void down()
{
if(mark)
{
if(l) l->set(mark);
if(r) r->set(mark);
mark=0;
}
}
void cotr()
{
if(l) min(mn,l->mn),max(mx,l->mx);
if(r) min(mn,r->mn),max(mx,r->mx);
up();
}
void force(const pan &kre)
{
if(kis>0) return;
if(!cnt) *ptr=kre.val;
down();
if(l) l->force(kre);
if(r) r->force(kre);
up();
}
void check(const pan &kre)
{
if(kis<=0||kre.outer(mn,mx)) return;
if(kre.inner(mn,mx))
{
set(1); force(kre);
return;
}
down();
if(l) l->check(kre);
if(r) r->check(kre);
if(kre.inner(p,p)&&!(--cnt)) *ptr=kre.val;
up();
}
}*rt;
struct fruit
{
pnt p;
int cnt;
int *ptr;
bool operator< (const fruit &b) const {return p<b.p;}
}g[gm];
node *build(int l=1,int r=q,int dir=0)
{
if(r<l) return 0;
cmp=dir; int mid=(l+r)>>1;
std::nth_element(g+l,g+mid,g+r+1);
node *res=new node(g[mid].p,g[mid].cnt,g[mid].ptr);
res->l=build(l,mid-1,dir^1);
res->r=build(mid+1,r,dir^1);
res->cotr();
return res;
}
struct e
{
int t;
e *n;
e(int t,e *n):t(t),n(n){}
}*f[gm];
int fa[gm][16],dfn[gm],sz[gm],dep[gm],ct;
void dfs(int x)
{
dfn[x]=++ct; sz[x]=1;
for(e *i=f[x];i;i=i->n)
{
if(i->t==*fa[x]) continue;
*fa[i->t]=x;
dep[i->t]=dep[x]+1;
dfs(i->t);
sz[x]+=sz[i->t];
}
}
inline int jump(int x,int k)
{
int cnt=0;
while(k)
{
if(k&1) x=fa[x][cnt];
++cnt;
k>>=1;
}
return x;
}
#define swap(a,b) ((a)^=(b)^=(a)^=(b))
int ans[gm];
int main()
{
scanf("%d%d%d",&n,&p,&q);
for(int i=1;i<n;++i)
{
int u,v; scanf("%d%d",&u,&v);
f[u]=new e(v,f[u]); f[v]=new e(u,f[v]);
}
dfs(1);
for(int i=1,j=log2(n);i<=j;++i)
for(int k=1;k<=n;++k)
fa[k][i]=fa[fa[k][i-1]][i-1];
for(int i=1;i<=p;++i)
{
int a,b,c; scanf("%d%d%d",&a,&b,&c);
if(dep[a]>dep[b]) swap(a,b);
int x1,x2,y1,y2;
if(jump(b,dep[b]-dep[a])!=a)
{
x1=dfn[a],x2=dfn[a]+sz[a]-1,y1=dfn[b],y2=dfn[b]+sz[b]-1;
if(y1<x1) swap(x1,y1),swap(x2,y2);
pst[++tot]=(pan){pnt(x1,y1),pnt(x2,y2),c};
}
else
{
a=jump(b,dep[b]-dep[a]-1);
x1=1,x2=dfn[a]-1,y1=dfn[b],y2=dfn[b]+sz[b]-1;
pst[++tot]=(pan){pnt(x1,y1),pnt(x2,y2),c};
x1=dfn[b],x2=dfn[b]+sz[b]-1,y1=dfn[a]+sz[a],y2=n;
pst[++tot]=(pan){pnt(x1,y1),pnt(x2,y2),c};
}
}
std::sort(pst+1,pst+tot+1);
for(int i=1;i<=q;++i)
{
int u,v,k; scanf("%d%d%d",&u,&v,&k);
u=dfn[u],v=dfn[v];
if(u>v) swap(u,v);
g[i]=(fruit){pnt(u,v),k,ans+i};
}
rt=build();
for(int i=1;i<=tot;++i)
{
rt->check(pst[i]);
}
for(int i=1;i<=q;++i) printf("%d\n",ans[i]);
return 0;
}