GEMA is hosting Q rounds of 10-hour-long contests in honor of the great Danfto. Everybody wants to honor Danfto, but 10 hours is a really long time, so people are wondering whether to go or not.
A person's decision is affected by their best friend's decision. Each person has at most one best friend and there are no cycles (this is not a Disney movie and there are no reciprocated friendships), meaning that if Nicoleta's best friend is Sancho and Sancho's best friend is Teoo, Teoo's best friend is not Sancho nor Nicoleta. In this case, Nicoleta will participate only if Sancho does, Sancho will participate only if Teoo does, and Teoo doesn't have a best friend so he doesn't depend on anyone.
People can also depend on some other factors like the weather, their mood or their mothers' permission. So there's no guarantee that they will participate even if their best friend does.
Now the rounds have passed and you are very curious about who were the brave souls that went to each round. You asked Tomaso if Teoo participated in a round, but Tomaso was drunk, so instead of replying yes or no, he told you that Nicoleta participated. You can deduce that Teoo went to the contest too because Nicoleta would only participate if Sancho did, which in turn would only go if Teoo did.
You asked Tomaso Q questions, one for each round, of whether y participated, and he told you that x did. Is it possible to know for sure if y participated in the round given that x did?
Input
The first line of the input contains two integers, N (2 ≤ N ≤ 1 × 105) and Q (1 ≤ Q ≤ 2 × 105), indicating the number of people invited to the Danfto honor rounds and the number of questions you asked Tomaso.
The next line contains N integers. The i-th integer ai (ai = - 1 or 0 ≤ ai ≤ N - 1)indicates that the i-th person will only participate in a round if the ai-th person does. If a person doesn't depend on anyone, ai is -1.
Q lines follow. The j-th line contains two integers xj and yj (0 ≤ xj, yj ≤ N - 1)indicating that you want to know if the yj-th person participated in the j-th round, and Tomaso told you that the xj-th person did.
Output
For each query, output "Yes" if you can determine that the y-th person participated and output "No" otherwise.
Example
Input
3 2 1 2 -1 0 2 2 0
Output
Yes No
dfs序
https://www.cnblogs.com/stxy-ferryman/p/7741970.html(更详细的解释,还有欧拉序)
这个题是要通过子节点去推出父节点的状态。给出两点x,y,判断y是否为x的父节点。如果每次都用dfs去搜索肯定会超时。
dfs序就是dfs遍历一遍,记录遍历每个节点的最早时间和最晚时间,通过这两个值判断两点的关系。(默认往下搜时间+1,回溯不加时间)
代码:
//Full of love and hope for life
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#define inf 0x3f3f3f3f
//https://paste.ubuntu.com/
using namespace std;
typedef long long ll;
const ll maxn=100010;
int flag[2*maxn],l[maxn],r[maxn],m[maxn],ans;
vector<int>n[maxn];
void dfs(int x){
l[x]=++ans;
int len=n[x].size();
for(int i=0;i<len;i++){
if(flag[n[x][i]]==0){
flag[n[x][i]]=1;
dfs(n[x][i]);
flag[n[x][i]]=0;
}
}
r[x]=ans;
}
int main()
{
ios::sync_with_stdio(false);
int a,b,c,x,y;
cin >> a >> b;
memset(flag,0,sizeof(flag));
memset(m,0,sizeof(m));
for(int i=0;i<a;i++){
cin >> c;
if(c!=-1){
n[c].push_back(i);
m[i]++;
}
}
for(int i=0;i<a;i++){
if(m[i]==0){
flag[i]=1;
dfs(i);
}
}
for(int i=1;i<=b;i++){
cin >> x >> y;
if(l[x]>=l[y]&&r[x]<=r[y]){
cout << "Yes" << endl;;
}
else{
cout << "No" << endl;
}
}
return 0;
}