SDOI2015 寻宝游戏

#include
#include
#include
using namespace std;
#define int long long
#define N 100010
struct edge{
    int nxt,to,w;
} e[N<<1];
set 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[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=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;
}

转载于:https://www.cnblogs.com/pelom/p/10659201.html

你可能感兴趣的:(SDOI2015 寻宝游戏)