原题链接:蓝桥杯2018年第九届真题-版本分支
解题思路:
常规的求祖先方法往往一次向上移动1,采用倍增的方法一次向上移动2^k,nlogn处理出倍增数组,logn查询。
注意事项:
提一个题解区没说的,不要用cin读,会超时。
参考代码:
#include<bits/stdc++.h> using namespace std; #define maxx 130000 #define int long long int n,q,a,b; int fa[maxx]; int faaa[maxx][22]; vector<int> G[maxx]; int dep[maxx]; void starting() { for(int i=1;i<=n;++i) faaa[i][0]=fa[i]; for(int j=1;j<=20;++j) //循环位置 for(int i=1;i<=n;++i) faaa[i][j]=faaa[faaa[i][j-1]][j-1]; } void dfs(int i) { for(int j=0;j<G[i].size();++j) {dep[G[i][j]]=dep[i]+1; dfs(G[i][j]);} } int cal(int x,int y) { if(dep[x]>dep[y]) return 0; int cha=dep[y]-dep[x]; for(int i=0;i<20;++i) { if(cha%2==1) y=faaa[y][i]; cha/=2; } if(y==x) return 1; else return 0; } signed main() { scanf("%d %d",&n,&q); for(int i=1;i<n;++i) {scanf("%d %d",&a,&b); fa[b]=a; G[a].push_back(b); } for(int i=1;i<=n;++i) if(fa[i]==0) dfs(i); starting(); for(int i=1;i<=q;++i) { scanf("%d %d",&a,&b); if(cal(a,b)) cout<<"YES\n"; else cout<<"NO\n"; } }
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复