Pelom777's Blog

洛谷 github
Pelom的头像
Pelom777
Stop crying and smile.——Angels of Death
/*tool*/

SDOI2015 寻宝游戏

#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
#define int long long
#define N 100010
struct edge{
    int nxt,to,w;
} e[N<<1];
set<int> S;
int n,m,x,y,z;
char c;
int cnt,tot,ans;
int head[N],fa[N],siz[N],son[N],dep[N],top[N],dis[N],dfn[N],id[N];
bool vis[N];
inline void add(int u,int v,int w){
    e[++cnt].nxt=head[u];
    e[cnt].to=v;
    e[cnt].w=w;
    head[u]=cnt;
}
void dfs1(int u){
    siz[u]=1;
    dep[u]=dep[fa[u]]+1;
    dfn[u]=++tot;
    id[tot]=u;
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].to;
        if(v==fa[u])
            continue;
        fa[v]=u;
        dis[v]=dis[u]+e[i].w;
        dfs1(v);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]])
            son[u]=v;
    }
}
void dfs2(int u,int t){
    top[u]=t;
    if(!son[u])
        return ;
    dfs2(son[u],t);
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].to;
        if(v==fa[u] || v==son[u])
            continue;
        dfs2(v,v);
    }
}
inline int LCA(int x,int y){
    for(;top[x]!=top[y];){
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])
        swap(x,y);
    return x;
}
inline int calc(int x,int y){
    return dis[x]+dis[y]-dis[LCA(x,y)]*2;
}
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<n;i++){
        scanf("%lld%lld%lld",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    dfs1(1);
    dfs2(1,1);
    S.insert(0);
    S.insert(n+1);
    for(int i=1;i<=m;i++){
        scanf("%lld",&x);
        int sum=0;
        if(!vis[x])
            S.insert(dfn[x]);
        int l=*--S.find(dfn[x]),r=*++S.find(dfn[x]);
        if(l>=1)
            sum+=calc(id[l],x);
        if(r<=n)
            sum+=calc(id[r],x);
        if(l>=1 && r<=n)
            sum-=calc(id[l],id[r]);
        if(!vis[x])
            ans+=sum;
        else{
            S.erase(dfn[x]);
            ans-=sum;
        }
        l=*++S.find(0),r=*--S.find(n+1);
        if(l<1 || r>n)
            printf("%lld\n",ans);
        else printf("%lld\n",ans+calc(id[l],id[r]));
        vis[x]=!vis[x];
    }
    return 0;
}
posted @ 2019-04-05 17:14  Pelom  阅读(138)  评论(0编辑  收藏  举报