祖孙询问 答案
Posted retr67
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了祖孙询问 答案相关的知识,希望对你有一定的参考价值。
#include <stdio.h> #define re register inline void read(int &x) { x=0;char c=getchar();bool p=1; for(; ‘0‘>c || c>‘9‘; c=getchar()) if(c==‘-‘) p=0; for(; ‘0‘<=c && c<=‘9‘; c=getchar()) x=(x<<1)+(x<<3)+(c^48); p?:x=-x; } struct node {int to,next;}; node edge[80001]; int cnt; int head[40001],d[40001]; int fa[40001][18]; inline void add(int u,int v) { edge[++cnt]=(node){v,head[u]}; head[u]=cnt; } inline void dfs(int u) { for(re int i=1; i<=17; ++i) { if(d[u]<(1<<i)) break; fa[u][i]=fa[fa[u][i-1]][i-1]; } for(re int i=head[u]; i; i=edge[i].next) { int v=edge[i].to; if(v==fa[u][0]) continue; fa[v][0]=u; d[v]=d[u]+1; dfs(v); } } inline int LCA(int u,int v) { if(d[u]<d[v]) u^=v,v^=u,u^=v; for(re int i=0; i<=17; ++i) if((d[u]-d[v])&(1<<i)) u=fa[u][i]; if(u==v) return u; for(re int i=17; i>=0; --i) if(fa[u][i]^fa[v][i]) u=fa[u][i],v=fa[v][i]; return fa[u][0]; } int main() { int N,root; read(N); for(re int i=1; i<=N; ++i) { int A,B; read(A),read(B); if(B^-1) add(A,B),add(B,A); else root=A; } dfs(root); int M; read(M); for(re int i=1; i<=M; ++i) { int X,Y; read(X),read(Y); if(X^Y) { int l=LCA(X,Y); if(l==X) puts("1"); else if(l==Y) puts("2"); else puts("0"); } else puts("0"); } return 0; }
1059: 祖孙询问
- Time Limit
- 1000 ms
- Memory Limit
- 131072 KBytes
- Judge
- Standard Judge
- Solved
- 76
- Submit
- 157
Description
已知一棵n个节点的有根树。有m个询问。每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。
Input Format
输入第一行包括一个整数n表示节点个数。
接下来n行每行一对整数对a和b表示a和b之间有连边。如果b是-1,那么a就是树的根。
第n+2行是一个整数m表示询问个数。
接下来m行,每行两个正整数x和y。
Output Format
对于每一个询问,输出1:如果x是y的祖先,输出2:如果y是x的祖先,否则输出0。
Sample Input
10 234 -1 12 234 13 234 14 234 15 234 16 234 17 234 18 234 19 234 233 19 5 234 233 233 12 233 13 233 15 233 19
Sample Output
1 0 0 0 2
Hint
对于30%的数据,n,m≤1000。
对于100%的数据,n,m≤40000,每个节点的编号都不超过40000。
以上是关于祖孙询问 答案的主要内容,如果未能解决你的问题,请参考以下文章
Jzoj 3054NOIP2012模拟10.27倍增祖孙询问
2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)