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
", ans+t);
92     }
93     return 0;
94 }
原文地址:https://www.cnblogs.com/mzl0707/p/5471474.html