没什么好说的,裸树上点对距离,用lca,nlogn求解,结果因为主席树打多了。。统计答案的时候写成f[x]+f[y]-f[lca]-f[fa[lca]],这里存储信息方式不同,一个是点,一个是边,所以不能减去fa,而是2*f[lca]。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+5;
int head[N*2],next[N*2],val[N*2],go[N*2],tot;
int n,m,q;
int dis[N],dep[N],fa[N][22];
inline void dfs(int x)
{
fo(i,1,20)fa[x][i]=0;
fo(i,1,20)fa[x][i]=fa[fa[x][i-1]][i-1];
int i=head[x];
while (i)
{
int v=go[i];
if (v!=fa[x][0])
{
fa[v][0]=x;
dis[v]=dis[x]+val[i];
dep[v]=dep[x]+1;
dfs(v);
}
i=next[i];
}
}
inline int get(int x,int y)
{
if (dep[x]<dep[y])swap(x,y);
fd(i,20,0)
if (dep[fa[x][i]]>=dep[y])x=fa[x][i];
if (x==y)return x;
fd(i,20,0)
if (fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
inline void add(int x,int y,int z)
{
go[++tot]=y;
val[tot]=z;
next[tot]=head[x];
head[x]=tot;
}
int main()
{
scanf("%d%d",&n,&q);
fo(i,1,n-1)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
dep[1]=1;
dfs(1);
fo(i,1,q)
{
int x,y;
scanf("%d%d",&x,&y);
if (x>y)swap(x,y);
int lca=get(x,y);
printf("%d\n",dis[x]+dis[y]-2*dis[lca]);
}
}