luogu3320 寻宝游戏 (dfs序+倍增lca+set)

一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的

所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt)

删掉一个点同理

这个可以用set维护

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=1e5+10;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 int eg[maxn*2][3],egh[maxn],ect;
16 int fa[maxn][20],dep[maxn],N,M;
17 int dfn[maxn],tot,id[maxn];
18 ll dis[maxn];
19 set<int> nds;
20 
21 inline void adeg(int a,int b,int c){
22     eg[++ect][0]=b;eg[ect][1]=egh[a];eg[ect][2]=c;egh[a]=ect;
23 }
24 
25 void dfs(int x){
26     dfn[x]=++tot;id[tot]=x;
27     for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++)
28         fa[x][i+1]=fa[fa[x][i]][i];
29     for(int i=egh[x];i;i=eg[i][1]){
30         int b=eg[i][0];if(b==fa[x][0]) continue;
31         dep[b]=dep[x]+1,fa[b][0]=x;
32         dis[b]=dis[x]+eg[i][2];
33         dfs(b);
34     }
35 }
36 
37 ll getdis(int x,int y){
38     ll re=dis[x]+dis[y];
39     if(dep[x]<dep[y]) swap(x,y);
40     for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){
41         if(dep[fa[x][i]]>=dep[y])
42             x=fa[x][i];
43     }
44     if(x==y) return re-2*dis[x];
45     for(int i=log2(dep[x]);i>=0;i--){
46         if(fa[x][i]!=fa[y][i])
47             x=fa[x][i],y=fa[y][i];
48     }
49     return re-2*dis[fa[x][0]];
50 }
51 
52 int main(){
53     //freopen("","r",stdin);
54     int i,j,k;
55     N=rd(),M=rd();
56     for(i=1;i<N;i++){
57         int a=rd(),b=rd(),c=rd();
58         adeg(a,b,c);adeg(b,a,c);
59     }
60     dep[1]=1;dfs(1);
61     ll ans=0;
62     for(i=1;i<=M;i++){
63         int x=rd();
64         set<int>::iterator it=nds.lower_bound(dfn[x]);
65         if(*it==dfn[x]){
66             if(nds.size()!=1){
67                 int a,b;
68                 if(it==nds.begin()) it=nds.end();it--;
69                 a=id[*it];
70                 it=nds.upper_bound(dfn[x]);
71                 if(it==nds.end()) it=nds.begin();
72                 b=id[*it];
73                 ans+=getdis(a,b)-getdis(a,x)-getdis(b,x);
74             }
75             nds.erase(dfn[x]);
76         }else{
77             nds.insert(dfn[x]);
78             if(nds.size()!=1){
79                 int a,b;
80                 it=nds.lower_bound(dfn[x]);
81                 if(it==nds.begin()) it=nds.end();it--;
82                 a=id[*it];
83                 it=nds.upper_bound(dfn[x]);
84                 if(it==nds.end()) it=nds.begin();
85                 b=id[*it];
86                 ans-=getdis(a,b)-getdis(a,x)-getdis(b,x);
87             }
88         }
89         printf("%lld\n",ans);
90     }
91     return 0;
92 }

 

posted @ 2018-10-18 17:02  Ressed  阅读(189)  评论(0编辑  收藏  举报