bzoj3991: [SDOI2015]寻宝游戏--DFS序+LCA+set动态维护
之前貌似在hdu还是poj上写过这道题。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<set> 5 #define maxn 100010 6 #define INF 0x7fffffff 7 using namespace std; 8 struct node{ 9 int to,cost,next; 10 }e[maxn*2]; 11 int n,m,u,v,c,logn,tot,time,x; 12 int fa[maxn][19],head[maxn],dep[maxn],id[maxn],pos[maxn]; 13 long long dis[maxn][19]; 14 bool flag[maxn]; 15 long long ans,t; 16 set<int> st; 17 18 inline void insert(int u, int v, int c){ 19 e[++tot].to=v; 20 e[tot].cost=c; 21 e[tot].next=head[u]; 22 head[u]=tot; 23 } 24 25 inline void dfs(int u, int f, int d, int c){ 26 pos[u]=++time; id[time]=u; 27 dep[u]=d; 28 fa[u][0]=f; dis[u][0]=c; 29 for (int i=1; i<=logn; i++) fa[u][i]=fa[fa[u][i-1]][i-1]; 30 for (int i=1; i<=logn; i++) dis[u][i]=dis[u][i-1]+dis[fa[u][i-1]][i-1]; 31 for (int i=head[u]; i!=-1; i=e[i].next) 32 if (e[i].to!=f) dfs(e[i].to,u,d+1,e[i].cost); 33 } 34 35 inline long long lca(int u, int v){ 36 long long sum=0; 37 if (dep[u]>dep[v]) swap(u,v); 38 while (dep[u]<dep[v]){ 39 for (int i=logn; i>=0; i--) 40 if (dep[u]<dep[fa[v][i]]){ 41 sum+=dis[v][i]; 42 v=fa[v][i]; 43 } 44 sum+=dis[v][0]; 45 v=fa[v][0]; 46 } 47 if (u==v) return sum; 48 for (int i=logn; i>=0; i--) 49 if (fa[u][i]!=fa[v][i]){ 50 sum+=dis[u][i]+dis[v][i]; 51 u=fa[u][i]; v=fa[v][i]; 52 } 53 sum+=dis[u][0]+dis[v][0]; 54 return sum; 55 } 56 57 int main(){ 58 scanf("%d%d", &n, &m); 59 logn=0; while ((1<<logn)<n) logn++; 60 tot=-1; memset(head,-1,sizeof(head)); 61 for (int i=1; i<n; i++){ 62 scanf("%d%d%d", &u, &v, &c); 63 insert(u,v,c); 64 insert(v,u,c); 65 } 66 time=0; 67 dfs(1,0,1,0); 68 st.insert(-INF); st.insert(INF); 69 while (m--){ 70 scanf("%d", &x); 71 if (!flag[x]){ 72 flag[x]=1; 73 int l=*--st.lower_bound(pos[x]), r=*st.upper_bound(pos[x]); 74 st.insert(pos[x]); 75 if (l !=-INF) ans+=lca(id[l],x); 76 if (r != INF) ans+=lca(x,id[r]); 77 if (l!=-INF && r!=INF) ans-=lca(id[l],id[r]); 78 } 79 else{ 80 flag[x]=0; 81 st.erase(pos[x]); 82 int l=*--st.lower_bound(pos[x]), r=*st.upper_bound(pos[x]); 83 if (l!=-INF) ans-=lca(id[l],x); 84 if (r!= INF) ans-=lca(x,id[r]); 85 if (l!=-INF && r!=INF) ans+=lca(id[l],id[r]); 86 } 87 if (st.size()>=3){ 88 int l=*++st.lower_bound(-INF), r=*--st.lower_bound(INF); 89 t=lca(id[l],id[r]); 90 } 91 printf("%lld\n", ans+t); 92 } 93 return 0; 94 }