1. 程式人生 > >Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

最大 i++ using urn its -- spa 多少 !=

題意:給出 一顆樹,然後q個詢問,每個詢問給出3個點,讓我們自己選擇一個起點一個終點,這條路線上的點標記,問第三個點到終點的最多標記點是多少

思路:第三個點到終點的標記點,肯定是第三個點與起點的最近公共祖先到終點的標記點。我們可以求出三個點的的三種最近公共祖先,取深度最大的點K,然後求K到三個點的距離+1

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10;
 4 
 5 const int DEG=17;
 6 vector<int> e[N];
 7 int dep[N];
8 int fa[N][DEG]; 9 10 void dfs(int u){ 11 for(int i=1;i<DEG;i++){ 12 fa[u][i]=fa[fa[u][i-1]][i-1]; 13 } 14 for(int i=0;i<e[u].size();i++){ 15 int v=e[u][i]; 16 dep[v]=dep[u]+1; 17 fa[v][0]=u; 18 dfs(v); 19 } 20 } 21 int lca(int u,int v){
22 if(dep[u]<dep[v]) swap(u,v); 23 for(int i=0,d=dep[u]-dep[v];d;i++,d>>=1){ 24 if(d&1) u=fa[u][i]; 25 } 26 if(u==v) return v; 27 for(int i=DEG-1;i>=0;i--){ 28 if(fa[u][i]!=fa[v][i]){ 29 u=fa[u][i];v=fa[v][i]; 30 } 31 } 32 return
fa[u][0]; 33 } 34 int hh(int u,int v){ 35 return dep[u]+dep[v]-2*dep[lca(u,v)]; 36 } 37 int main(){ 38 int n,q; 39 int x; 40 scanf("%d%d",&n,&q); 41 for(int i=2;i<=n;i++){ 42 scanf("%d",&x); 43 e[x].push_back(i); 44 } 45 dep[1]=1; 46 dfs(1); 47 int k[4]; 48 while(q--){ 49 for(int i=1;i<=3;i++) scanf("%d",&k[i]); 50 int x1=lca(k[1],k[2]),x2=lca(k[1],k[3]),x3=lca(k[2],k[3]); 51 int x; 52 if(dep[x1]>dep[x2]) x=x1;else x=x2; 53 if(dep[x]<dep[x3]) x=x3; 54 int y1=hh(x,k[1]),y2=hh(x,k[2]),y3=hh(x,k[3]); 55 56 cout<<max(max(y1,y2),y3)+1<<endl; 57 } 58 return 0; 59 }

Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground