整体二分的做法题解很多:http://blog.csdn.net/thy_asdf/article/details/50363672
树套树么 ORZ
打的整体二分
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=100005;
namespace TREE{
#define V G[p].v
struct edge{
int u,v,next;
};
edge G[N<<1];
int head[N],inum;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int clk;
int size[N],pre[N],last[N],fat[N][21],depth[N];
inline void dfs(int u,int fa){
size[u]=1; pre[u]=++clk; depth[u]=depth[fa]+1; fat[u][0]=fa;
for (int k=1;k<=20;k++) fat[u][k]=fat[fat[u][k-1]][k-1];
for (int p=head[u];p;p=G[p].next)
if (V!=fa)
dfs(V,u),size[u]+=size[V];
last[u]=pre[u]+size[u]-1;
}
inline int LCA(int u,int v){
if (depth[u]<depth[v]) swap(u,v);
for (int k=20;~k;k--)
if ((depth[u]-depth[v])&(1<<k))
u=fat[u][k];
if (u==v) return u;
for (int k=20;~k;k--)
if (fat[u][k]!=fat[v][k])
u=fat[u][k],v=fat[v][k];
return fat[u][0];
}
inline int SecLCA(int x,int y){
for (int k=20;~k;k--)
if (depth[fat[x][k]]>depth[y])
x=fat[x][k];
return x;
}
}
int n,P,Q;
int ans[N];
struct Query{
int x,y,k;
int idx;
}que[N],tmp[N];
int qtot;
struct Matrix{
int x1,x2,y1,y2,key;
bool operator < (const Matrix &B) const{
return key<B.key;
}
}mat[N<<1];
int mtot;
namespace BIT{
#define lowbit(x) ((x)&-(x))
int c[N];
inline void add(int x,int t){
for (int i=x;i<=n;i+=lowbit(i))
c[i]+=t;
}
inline void add(int l,int r,int t){
add(l,t); add(r+1,-t);
}
inline int query(int x){
int ret=0;
for (int i=x;i;i-=lowbit(i))
ret+=c[i];
return ret;
}
}
struct event{
int x,y1,y2,r;
event() { }
event(int x,int y1,int y2,int r):x(x),y1(y1),y2(y2),r(r) { }
bool operator < (const event &B) const{
return x==B.x?(r>B.r):(x<B.x);
}
}eve[N<<2];
int tot;
int cnt[N<<2];
inline void Solve(int l,int r,int ql,int qr){
if (l==r){
for (int i=ql;i<=qr;i++) ans[que[i].idx]=mat[l].key;
return;
}
int mid=(l+r)>>1;
tot=0;
for (int i=l;i<=mid;i++) eve[++tot]=event(mat[i].x1,mat[i].y1,mat[i].y2,1),eve[++tot]=event(mat[i].x2,mat[i].y1,mat[i].y2,-1);
for (int i=ql;i<=qr;i++) eve[++tot]=event(que[i].x,que[i].y,i,0);
sort(eve+1,eve+tot+1);
for (int i=1;i<=tot;i++)
if (eve[i].r==1)
BIT::add(eve[i].y1,eve[i].y2,1);
else if (eve[i].r==-1)
BIT::add(eve[i].y1,eve[i].y2,-1);
else if (eve[i].r==0)
cnt[eve[i].y2]=BIT::query(eve[i].y1);
int L=ql-1,R=qr+1;
for (int i=ql;i<=qr;i++)
if (cnt[i]<que[i].k)
tmp[--R]=que[i],tmp[R].k-=cnt[i];
else
tmp[++L]=que[i];
for (int i=ql;i<=qr;i++)
que[i]=tmp[i];
if (ql<=L) Solve(l,mid,ql,L);
if (R<=qr) Solve(mid+1,r,R,qr);
}
int main()
{
using namespace TREE;
int iu,iv,ik,w,lca;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(P); read(Q);
for (int i=1;i<n;i++)
read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum);
dfs(1,0);
for (int i=1;i<=P;i++)
{
read(iu); read(iv); read(ik);
if (pre[iu]>pre[iv]) swap(iu,iv);
if ((lca=LCA(iu,iv))==iu)
{
w=SecLCA(iv,iu);
if (pre[w]-1>0)
{
mat[++mtot].key=ik;
mat[mtot].x1=1; mat[mtot].x2=pre[w]-1; mat[mtot].y1=pre[iv]; mat[mtot].y2=last[iv];
}
if (last[w]+1<=n)
{
mat[++mtot].key=ik;
mat[mtot].x1=pre[iv]; mat[mtot].x2=last[iv]; mat[mtot].y1=last[w]+1; mat[mtot].y2=n;
}
}
else
{
mat[++mtot].key=ik;
mat[mtot].x1=pre[iu]; mat[mtot].x2=last[iu]; mat[mtot].y1=pre[iv]; mat[mtot].y2=last[iv];
}
}
sort(mat+1,mat+mtot+1);
for (int i=1;i<=Q;i++)
{
read(iu); read(iv); read(ik);
if (pre[iu]>pre[iv]) swap(iu,iv);
que[++qtot].k=ik; que[qtot].x=pre[iu]; que[qtot].y=pre[iv]; que[qtot].idx=i;
}
Solve(1,mtot,1,qtot);
for (int i=1;i<=Q;i++) printf("%d\n",ans[i]);
return 0;
}