时间限制: 1 Sec 内存限制: 128 MBnode
7
B -1
Q 1
B 1
B 2
Q 3
B 2
Q 2
0
2
1
The example input corresponds to this network of barns:
(1)
\
(2)---(4)
/
(3)
In query 1, we build barn number 1. In query 2, we ask for the distance of 1 to the farthest connected barn. Since barn 1 is connected to no other barns, the answer is 0. In query 3, we build barn number 2 and connect it to barn 1. In query 4, we build barn number 3 and connect it to barn 2. In query 5, we ask for the distance of 3 to the farthest connected barn. In this case, the farthest is barn 1, which is 2 units away. In query 6, we build barn number 4 and connect it to barn 2. In query 7, we ask for the distance of 2 to the farthest connected barn. All three barns 1, 3, 4 are the same distance away, which is 1, so this is our answer.c++
分析:题意:给定一个森林,在建森林的过程当中有一些询问,距离某个点最远的点的距离;ui
考虑分治,对于每一个点的祖先,要么通过祖先,要么不通过;this
若是通过,考虑维护这个祖先的最大的两个点的深度,这两个点不在同一棵子树且已经被标记;更新答案分在不在同一子树里便可;spa
若是不通过,则能够递归到子树,对于分治来讲,维护重心,每一个点有log个祖先;code
注意若是两个点被标记则lca也被标记过;orm
代码:blog
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+10,mod=1e9+7,inf=0x3f3f3f3f; int n,m,k,t,rt,a[maxn],sz[maxn],all; bool vis[maxn]; vector<int>e[maxn]; struct node { int mx1,mx2,mxid; vector<pair<int,int> >anc; }p[maxn]; int getroot(int x,int y=0) { for(int i=0;i<e[x].size();i++) { int z=e[x][i]; if(z==y||vis[z])continue; if(sz[z]*2>=all)return getroot(z,x); } return x; } void getdep(int x,int y,int dep) { p[x].anc.push_back({rt,dep}); for(int i=0;i<e[x].size();i++) { int z=e[x][i]; if(z==y||vis[z])continue; getdep(z,x,dep+1); } } void getsz(int x,int y=0) { sz[x]=1; for(int i=0;i<e[x].size();i++) { int z=e[x][i]; if(z==y||vis[z])continue; getsz(z,x); sz[x]+=sz[z]; } } void dfs(int x) { getsz(x); all=sz[x]; rt=getroot(x); getdep(rt,0,0); vis[rt]=true; for(int i=0;i<e[rt].size();i++) { int z=e[rt][i]; if(!vis[z])dfs(z); } } int main() { int i,j; scanf("%d",&m); int pos=0; for(i=1;i<=m;i++) { char str[2]; scanf("%s%d",str,&n); if(str[0]=='B') { a[i]=++pos; if(n==-1)continue; else e[n].push_back(pos),e[pos].push_back(n); } else a[i]=-n; } for(i=1;i<=pos;i++)if(!vis[i])dfs(i); pos=0; for(i=1;i<=m;i++) { int last=-1; if(a[i]>0) { ++pos; for(j=p[pos].anc.size()-1;j>=0;j--) { int fa=p[pos].anc[j].first,w=p[pos].anc[j].second; if(p[fa].mx1<=w) { if(p[fa].mxid!=last)p[fa].mx2=p[fa].mx1; p[fa].mx1=w; p[fa].mxid=last; } else if(p[fa].mx2<=w) { if(last!=p[fa].mxid)p[fa].mx2=w; } last=fa; } } else { int now=-a[i]; int ret=p[now].mx1; for(j=p[now].anc.size()-1;j>=0;j--) { int fa=p[now].anc[j].first,w=p[now].anc[j].second; if(fa>pos) { last=fa; continue; } if(last==p[fa].mxid)ret=max(ret,w+p[fa].mx2); else ret=max(ret,w+p[fa].mx1); last=fa; } printf("%d\n",ret); } } return 0; }