1. 程式人生 > >bzoj3991 [SDOI2015]尋寶遊戲

bzoj3991 [SDOI2015]尋寶遊戲

OS lld 集合 直接 d+ tor insert 維護 排序

虛樹,一直在想怎麽在虛樹裏快速插入一個節點,其實不需要。

考慮我們要求的是什麽,是按dfs序排序後的相鄰關鍵點的距離和,於是我們直接用一個set維護當前的關鍵點集合,並記錄當前的答案,有修改就在set裏插入或刪除就好了。

技術分享圖片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <set>
 7 #define N 100500
 8
using namespace std; 9 int e=1,head[N]; 10 struct edge{ 11 int v,w,next; 12 }ed[N<<1]; 13 int dep[N],fa[N][22],L[N],tot,n,m; 14 bool vis[N]; 15 long long val[N]; 16 struct cmp{ 17 bool operator () (int a,int b){ 18 return L[a]<L[b]; 19 } 20 }; 21 set<int ,cmp> s;
22 set<int ,cmp> :: iterator it; 23 void push(int u,int v,int w){ 24 ed[e].v=v;ed[e].w=w; 25 ed[e].next=head[u];head[u]=e++; 26 } 27 void dfs(int x,int d){ 28 dep[x]=d;L[x]=++tot; 29 for(int i=1;(1<<i)<=d;i++) 30 fa[x][i]=fa[fa[x][i-1]][i-1]; 31 for
(int i=head[x];i;i=ed[i].next){ 32 int v=ed[i].v; 33 if(v==fa[x][0])continue; 34 fa[v][0]=x;val[v]=val[x]+ed[i].w; 35 dfs(v,d+1); 36 } 37 } 38 int getlca(int x,int y){ 39 if(dep[x]<dep[y])swap(x,y); 40 for(int i=20;~i;i--) 41 if(dep[fa[x][i]]>=dep[y])x=fa[x][i]; 42 if(x==y)return x; 43 for(int i=20;~i;i--) 44 if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; 45 return fa[x][0]; 46 } 47 long long getdis(int x,int y){ 48 return val[x]+val[y]-2*val[getlca(x,y)]; 49 } 50 int size; 51 long long sum; 52 void work(int x,int v){ 53 int y,z; 54 it=s.find(x); 55 if(it!=s.begin())it--,y=*it; 56 else it=s.end(),it--,y=*it; 57 it=s.find(x);it++; 58 if(it!=s.end())z=*it; 59 else it=s.begin(),z=*it; 60 sum+=v*(getdis(x,y)+getdis(x,z)-getdis(y,z)); 61 } 62 void del(int x){ 63 size--;vis[x]=0; 64 if(size<2)sum=0; 65 else work(x,-1); 66 s.erase(x); 67 } 68 void add(int x){ 69 size++;vis[x]=1; 70 s.insert(x); 71 if(size<2)sum=0; 72 else work(x,1); 73 } 74 int main(){ 75 scanf("%d%d",&n,&m); 76 for(int i=1,u,v,w;i<n;i++){ 77 scanf("%d%d%d",&u,&v,&w); 78 push(u,v,w); push(v,u,w); 79 } 80 dfs(1,1); 81 int x; 82 while(m--){ 83 scanf("%d",&x); 84 if(vis[x]) del(x); 85 else add(x); 86 printf("%lld\n",sum); 87 } 88 return 0; 89 }
View Code

bzoj3991 [SDOI2015]尋寶遊戲