题意
给一颗树,每条边有边权,每次询问\(u\)到\(v\)的路径中有多少边的边权小于等于\(k\)
分析
在树的每个点上建\(1\)到\(i\)的权值线段树,查询的时候同时跑\(u,v,lca(u,v)\)三个版本的线段树,查询\(1\)到\(k\)的树上差分和\(val[u]+val[v]-2*val[lca]\)
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
const int inf=1e9;
const int maxn=2e5+10;
int n,m,q;
int a[maxn],b[maxn];
typedef pair<int,int> pii;
vector<pii>g[maxn];
int top[maxn],sz[maxn],f[maxn],son[maxn],d[maxn];
int val[maxn*30],ls[maxn*30],rs[maxn*30],rt[maxn],tot;
int qu[maxn],qv[maxn],qk[maxn];
void bd(int l,int r,int &p){
val[++tot]=val[p],ls[tot]=ls[p],rs[tot]=rs[p],p=tot;
if(l==r) return;int mid=l+r>>1;
bd(l,mid,ls[p]);bd(mid+1,r,rs[p]);
}
void up(int k,int l,int r,int &p){
val[++tot]=val[p]+1,ls[tot]=ls[p],rs[tot]=rs[p],p=tot;
if(l==r) return;int mid=l+r>>1;
if(k<=mid) up(k,l,mid,ls[p]);
else up(k,mid+1,r,rs[p]);
}
int qy(int k,int l,int r,int a,int b,int c){
int ret=0;
if(l>=1&&r<=k) return val[a]+val[b]-2*val[c];
int mid=l+r>>1;
if(1<=mid) ret+=qy(k,l,mid,ls[a],ls[b],ls[c]);
if(k>mid) ret+=qy(k,mid+1,r,rs[a],rs[b],rs[c]);
return ret;
}
void add(int x){
int k=lower_bound(b+1,b+m+1,a[x])-b;
rt[x]=rt[f[x]];up(k,1,m,rt[x]);
}
void dfs1(int u){
sz[u]=1;d[u]=d[f[u]]+1;add(u);
for(pii x:g[u]){
if(x.fi==f[u]) continue;
a[x.fi]=x.se;f[x.fi]=u;
dfs1(x.fi);sz[u]+=sz[x.fi];
if(sz[x.fi]>sz[son[u]]) son[u]=x.fi;
}
}
void dfs2(int u,int t){
top[u]=t;
if(!son[u]) return;
dfs2(son[u],t);
for(pii x:g[u]){
if(x.fi==son[u]||x.fi==f[u]) continue;
dfs2(x.fi,x.fi);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(d[top[x]]>=d[top[y]]) x=f[top[x]];
else y=f[top[y]];
}
if(d[x]>=d[y]) return y;
else return x;
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1,a,x,c;i<n;i++){
scanf("%d%d%d",&a,&x,&c);
b[++m]=c;
g[a].pb(pii(x,c));
g[x].pb(pii(a,c));
}
for(int i=1;i<=q;i++){
scanf("%d%d%d",&qu[i],&qv[i],&qk[i]);
b[++m]=qk[i];
}
sort(b+1,b+m+1);
m=unique(b+1,b+m+1)-b-1;
bd(1,m,rt[0]);
dfs1(1);dfs2(1,1);
for(int i=1;i<=q;i++){
qk[i]=lower_bound(b+1,b+m+1,qk[i])-b;
printf("%d\n",qy(qk[i],1,m,rt[qu[i]],rt[qv[i]],rt[lca(qu[i],qv[i])]));
}
return 0;
}