// DFS version #include #include #include using namespace std; struct ACMTree { ACMTree( const vector& C ) { // 1. Reconstruction of the tree structure // i.e., to determine the first child for each ACM vector first_child_of( C.size() ); for(int a=0,p=1; a( number_of_acm ); id2 = vector( number_of_acm ); // 3. Let's DFS! // # 300,000 recursive call may happen, so you cannot DFS by recursion // # Mmm... int dfsID = 0; vector stk; stk.push_back(0); // 0=root while( !stk.empty() ) { int acm = stk.back(); stk.pop_back(); if( acm >= 0 ) { id1[acm] = dfsID++; stk.push_back(~acm); // trick for recording id2 (processed after all children) if( acm < C.size() ) for(int i=C[acm]-1; i>=0; --i) stk.push_back( first_child_of[acm]+i ); // push each child } else id2[~acm] = dfsID; // trick } } bool is_ancestor_descendant( int a, int b ) { // 4. Now we have the DFS visitaion order for each ACM, // So it is a quite easy task to determine the anc-des relation. return id1[a] <= id1[b] && id2[b] <= id2[a]; } vector id1, id2; }; int main() { int T; cin >> T; for( int caseNo=1; caseNo<=T; ++caseNo ) { // Input (numbers of children) vector C; { int N; cin >> N; while(N--) {int c; cin>>c; C.push_back(c);} } // Construct the tree ACMTree tree(C); // Answer for each query ... int count = 0; int M; cin >> M; while(M--) { int a, b; cin >> a >> b; if( tree.is_ancestor_descendant(a,b) ) count++; } // Output cout << count << endl; } }