對於查詢是否是祖先,我們可以對於每一個節點打上兩個dfs標記,如果一個點是另一個點的祖先,那麼它的兩個標記一定在祖先的範圍之內。【tarjan的時間戳的概念】
注意每個樣例輸出之間要輸空行
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<algorithm>
#define maxn 20022000
using namespace std;
typedef long long ll;
int n;
int child[maxn];
stack<int>st;
int clockk=0;
int vis[maxn];
struct a{
int l,r;
}state[maxn];
struct b{
int in,out;
}dfn[maxn];
void init(){
clockk=0;
while(!st.empty()) st.pop();
// for(int i=0;i<maxn;i++)
}
void dfs(){
for(int i=0;i<maxn;i++) vis[i]=0;
st.push(0);
while(!st.empty()){
int x=st.top();
if(!vis[x]){
vis[x]=1;
dfn[x].in=clockk++;
if(x<n){
int lchild=state[x].l,rchild=state[x].r;
for(int i=lchild;i<=rchild;i++) st.push(i);
}
}
else{
st.pop();
dfn[x].out=clockk++;
}
}
}
int main(){
int T,x,m;
scanf("%d",&T);
int cas=0;
while(T--){
init();
scanf("%d",&n);
int y=1;
for(int i=0;i<n;i++){
scanf("%d",&x);
state[i].l=y;
state[i].r=y+x-1;
y+=x;
}
dfs();
/* for(int i=0;i<10;i++){
printf("i=%d dfn[i].in=%d out=%d\n",i,dfn[i].in,dfn[i].out);
}
*/ int u,v;
scanf("%d",&m);
if(cas++) printf("\n");
printf("Case %d:\n",cas);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
bool f=false;
// printf("u=%d v=%d\n",u,v);
if(dfn[u].in<dfn[v].in&&dfn[u].out>dfn[v].out) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}