SDOI2015寻宝游戏
Posted zw130-lzr-blogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDOI2015寻宝游戏相关的知识,希望对你有一定的参考价值。
其实我做这题为时尚早
做这题之前先学习set
#include<bits/stdc++.h> #define MN 200050 #define ll long long using namespace std; set<ll>s; set<ll>::iterator it; ll n,m,cnt,head[MN],dfn[MN],dep[MN],num[MN]; ll vis[MN]; ll f[MN][21]; ll lg[MN]; ll dis[MN][18]; ll idx; ll Ans; struct tu ll v,nxt; ll w; e[MN]; void add(ll u,ll v,ll w) e[++cnt].v=v; e[cnt].nxt=head[u]; e[cnt].w=w; head[u]=cnt; void dfs(ll now,ll fa) dep[now]=dep[fa]+1; dfn[now]=++idx; f[now][0]=fa; num[idx]=now; for(ll i=1; i<=lg[dep[now]]; i++) f[now][i]=f[f[now][i-1]][i-1]; dis[now][i]=dis[now][i-1]+dis[f[now][i-1]][i-1]; for(ll i=head[now]; i; i=e[i].nxt) ll v=e[i].v; if(v!=fa) dis[e[i].v][0]=e[i].w; dfs(v,now); ll getl(ll x) it=s.lower_bound(x); if(it==s.begin())it=s.end(); return *--it; ll getr(ll x) it=s.lower_bound(x); if(++it==s.end())it=s.begin(); return *it; ll lca(ll x,ll y) if(dep[x]<dep[y])swap(x,y); ll ans=0; while(dep[x]!=dep[y]) ans+=dis[x][lg[dep[x]-dep[y]]]; x=f[x][lg[dep[x]-dep[y]]]; if(x==y)return ans; for(ll k=lg[dep[x]]; k>=0; k--) if(f[x][k]==f[y][k])continue; ans+=dis[x][k]+dis[y][k],x=f[x][k],y=f[y][k]; return ans+dis[x][0]+dis[y][0]; int main() scanf("%lld%lld\n",&n,&m); lg[0]=-1; ll sum=0; for(ll i=1; i<=n; i++) lg[i]=lg[i/2]+1; for(ll i=1; i<=n-1; i++) ll x,y,z; scanf("%lld%lld%lld",&x,&y,&z); add(x,y,z); add(y,x,z); dfs(1,0); ll x; for(ll i=1; i<=m; i++) scanf("%lld",&x); if (!vis[x]) vis[x]^=1; s.insert(dfn[x]); sum+=lca(num[getl(dfn[x])],x)+lca(num[getr(dfn[x])],x)-lca(num[getl(dfn[x])],num[getr(dfn[x])]); else vis[x]^=1; sum-=lca(num[getl(dfn[x])],x)+lca(num[getr(dfn[x])],x)-lca(num[getl(dfn[x])],num[getr(dfn[x])]); s.erase(dfn[x]); printf("%lld\n",sum); return 0;
以上是关于SDOI2015寻宝游戏的主要内容,如果未能解决你的问题,请参考以下文章