题意:求树上两点之间边权不超过k的边的个数。
思路:树剖之后建主席树,或者直接利用父子关系直接建树。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
#define ll long long
#define maxx 1e9
struct code
{
int l,r,d;
} tree[1000005];
int tot,treenum[100005];
vector<int>dap[100005];
vector<int>dvp[100005];
int fa[100005][20],deep[100005];
//void buid(int &t,int l,int r)
//{
// t=++tot;
// tree[t].d=0;
// if(l==r)
// return ;
// int mid=(l+r)/2;
// buid(tree[t].l,l,mid);
// buid(tree[t].r,mid+1,r);
//}//
void add(int &pre,int l,int r,int d)
{
tree[++tot]=tree[pre];
pre=tot;
tree[pre].d++;
int mid=(l+r)/2;
if(l==r)
return ;
if(d<=mid)add(tree[pre].l,l,mid,d);
else add(tree[pre].r,mid+1,r,d);
}
//void update(int& o, int l, int r, int last, int p)
//{
// o = ++ tot;
// ls[o] = ls[last];
// rs[o] = rs[last];
// sum[o] = sum[last] + 1;
// if(l == r) return;
// int m = (l + r) >> 1;
// if(p <= m) update(ls[o], l, m, ls[last], p);
// else update(rs[o], m + 1, r, rs[last], p);
//}//
int queuy(int x,int y,int l,int r,int tk,int k)
{
if(l>=tk&&k>=r)
return tree[y].d-tree[x].d;
int mid=(l+r)/2;
int ans=0;
if(mid>=tk)
ans+=queuy(tree[x].l,tree[y].l,l,mid,tk,k);
if(k>mid)
ans+=queuy(tree[x].r,tree[y].r,mid+1,r,tk,k);
return ans;
}
void dfs(int u,int f,int d)
{
fa[u][0]=f;
deep[u]=d;
int len=dap[u].size();
for(int i=0; i<len; i++)
{
int v=dap[u][i];
int w=dvp[u][i];
if(v==f)
continue;
treenum[v]=treenum[u];
add(treenum[v],0,maxx,w);
dfs(v,u,d+1);
}
}
void init(int n)
{
for(int i=1; i<20; i++)
{
for(int j=1; j<=n; j++)
fa[j][i]=fa[fa[j][i-1]][i-1];
}
}
int lca(int x,int y)
{
if(deep[x]<deep[y])
swap(x,y);
for(int i=19; i>=0; i--)
{
if(deep[fa[x][i]]>=deep[y])
x=fa[x][i];
}
if(x==y)
return x;
for(int i=19; i>=0; i--)
{
int tx=fa[x][i];
int ty=fa[y][i];
if(tx!=ty)
{
x=tx;
y=ty;
}
}
return fa[x][0];
}
int ans(int x,int y,int k)
{
int xy=lca(x,y);
return queuy(treenum[xy],treenum[x],0,maxx,0,k)+queuy(treenum[xy],treenum[y],0,maxx,0,k);
}
int main()
{
int n,m,s,e,v;
scanf("%d%d",&n,&m);
treenum[0]=0;
for(int i=1; i<n; i++)
{
scanf("%d%d%d",&s,&e,&v);
dap[s].push_back(e);
dap[e].push_back(s);
dvp[s].push_back(v);
dvp[e].push_back(v);
}
dfs(1,0,1);
init(n);
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&s,&e,&v);
printf("%d\n",ans(s,e,v));
}
return 0;
}