思路:将关键点按dfs序排序,然后显然就是dfs序中相邻的两个点的距离之和加上最后一个点到第一点的距离(YY一下很显然),动态维护就用splay就好了(我是一个不会用set的蒟蒻。。。。。)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 100005
int n,m,tot,deg,l,cnt;
int now[maxn],pre[2*maxn],son[2*maxn],val[2*maxn],dep[maxn],dfn[maxn];
int f[maxn][21];
long long ans,dis[maxn];
bool bo[maxn];
inline int read(){
int x=0;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar());
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x;
}
void add(int a,int b,int c){
son[++tot]=b;
pre[tot]=now[a];
now[a]=tot;
val[tot]=c;
}
void link(int a,int b,int c){
add(a,b,c),add(b,a,c);
}
void dfs(int x,int fa){
dep[x]=dep[fa]+1,dfn[x]=++deg;
for (int i=1;i<=l;i++) f[x][i]=f[f[x][i-1]][i-1];
for (int p=now[x];p;p=pre[p])
if (son[p]!=fa) f[son[p]][0]=x,dis[son[p]]=dis[x]+val[p],dfs(son[p],x);
}
int lca(int a,int b){
if (dep[a]<dep[b]) swap(a,b);int x=dep[a]-dep[b],t=0;
for (;x;x>>=1,t++) if (x&1) a=f[a][t];
if (a==b) return a;t=l;
for (;f[a][0]!=f[b][0];){
for (;f[a][t]==f[b][t];t--);
a=f[a][t],b=f[b][t];
}
return f[a][0];
}
struct splay_tree{
int ch[maxn][2],fa[maxn],note[maxn],val[maxn],pos[maxn],root,tot;
void rotate(int x){
int y=fa[x],z=fa[y],bo=note[x],bo1=note[y];
ch[y][bo]=ch[x][bo^1],fa[ch[x][bo^1]]=y;
ch[x][bo^1]=y,fa[y]=x;
fa[x]=z;if (bo1!=2) ch[z][bo1]=x;
note[x]=bo1,note[y]=bo^1,note[ch[y][bo]]=bo;
}
void splay(int x){
while (note[x]!=2){
if (note[x]==note[fa[x]]) rotate(fa[x]);
rotate(x);
}
root=x;
}
void insert(int x,int v,int p){
int y;
while (1){
y=ch[x][val[x]<v];
if (!y){
y=++tot;
val[y]=v,pos[y]=p;
if (x) note[y]=val[x]<v;else note[y]=2;
fa[y]=x,ch[y][0]=ch[y][1]=0;
if (x) ch[x][note[y]]=y;
break;
}
x=y;
}
splay(y);
}
int find(int v){
int x=root;
while (1){
if (val[x]==v) return splay(x),x;
if (val[x]<v) x=ch[x][1];else x=ch[x][0];
}
}
int pre(int x){
splay(x);x=ch[x][0];
while (ch[x][1]) x=ch[x][1];
return x;
}
int suc(int x){
splay(x);x=ch[x][1];
while (ch[x][0]) x=ch[x][0];
return x;
}
int getmin(){int x=root;while (ch[x][0]) x=ch[x][0];return x;}
int getmax(){int x=root;while (ch[x][1]) x=ch[x][1];return x;}
void del(int v){
int x=find(v);int y=suc(x),z=ch[x][0];
if (!y){
if (!z){root=0;return;}
fa[z]=0,note[z]=2,root=z;return;
}
fa[ch[x][1]]=0,note[ch[x][1]]=2,splay(y);
fa[z]=y,ch[y][0]=z,root=y;
}
}S;
int main(){
n=read(),m=read();l=log2(n);
for (int i=1,a,b,c;i<n;i++) a=read(),b=read(),c=read(),link(a,b,c);
dfs(1,0);
while (m--){
int x=read();bo[x]^=1;
if (bo[x]) S.insert(S.root,dfn[x],x),cnt++;
int a=S.pre(S.find(dfn[x])),b=S.suc(S.find(dfn[x]));
if (!a) a=S.getmax();if (!b) b=S.getmin();
a=S.pos[a],b=S.pos[b];
if (!bo[x]) S.del(dfn[x]),cnt--;
if (cnt<=1){puts("0"),ans=0;continue;}
ans+=(bo[x]?1:-1)*(dis[a]+dis[x]-2*dis[lca(a,x)]);
ans+=(bo[x]?1:-1)*(dis[x]+dis[b]-2*dis[lca(b,x)]);
ans+=(bo[x]?-1:1)*(dis[a]+dis[b]-2*dis[lca(a,b)]);
printf("%lld\n",ans);
}
return 0;
}