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 }