题目链接:【HDU】5420 Victor and Proposition
#include <bits/stdc++.h>
using namespace std ;
typedef long long LL ;
#define clr( a , x ) memset ( a , x , sizeof a )
const int MAXN = 100005 ;
const int MAXM = 4000005 ;
const int MAXE = 20000005 ;
struct Edge {
int v , n ;
Edge () {}
Edge ( int v , int n ) : v ( v ) , n ( n ) {}
} E[MAXE] ;
struct Node {
int l , r ;
} T[MAXM] ;
vector < int > G[MAXN] ;
int H[MAXM] , cntE ;
int root[MAXN] ;
bool vis[MAXM] ;
int dep[MAXN] ;
int idx[MAXN] ;
int dfn[MAXM] ;
int low[MAXM] ;
int num[MAXM] ;
int scc[MAXM] ;
int scc_cnt ;
int dfs_idx ;
int S[MAXM] ;
int top ;
int cur ;
int n ;
void init () {
top = 0 ;
cur = 1 ;
cntE = 0 ;
scc_cnt = 0 ;
dfs_idx = 0 ;
clr ( H , -1 ) ;
clr ( dfn , 0 ) ;
clr ( scc , 0 ) ;
clr ( vis , 0 ) ;
}
void addedge ( int u , int v ) {
E[cntE] = Edge ( v , H[u] ) ;
H[u] = cntE ++ ;
}
int newnode () {
T[cur].l = T[cur].r = 0 ;
return cur ++ ;
}
int add ( int x , int l , int r ) {
int o = newnode () ;
if ( l == r ) vis[idx[x] = o] = 1 ;
else {
int m = l + r >> 1 ;
if ( dep[x] <= m ) addedge ( o , T[o].l = add ( x , l , m ) ) ;
else addedge ( o , T[o].r = add ( x , m + 1 , r ) ) ;
}
return o ;
}
int merge ( int x , int y ) {
if ( !x ) return y ;
if ( !y ) return x ;
int o = newnode () ;
addedge ( o , x ) ;
addedge ( o , y ) ;
if ( T[x].l || T[y].l ) T[o].l = merge ( T[x].l , T[y].l ) ;
if ( T[x].r || T[y].r ) T[o].r = merge ( T[x].r , T[y].r ) ;
if ( T[o].l ) addedge ( o , T[o].l ) ;
if ( T[o].r ) addedge ( o , T[o].r ) ;
return o ;
}
int dfs ( int u ) {
root[u] = add ( u , 1 , n ) ;
for ( int i = 0 ; i < G[u].size () ; ++ i ) {
dep[G[u][i]] = dep[u] + 1 ;
root[u] = merge ( root[u] , dfs ( G[u][i] ) ) ;
}
return root[u] ;
}
void update ( int L , int R , int v , int o , int l , int r ) {
if ( L <= l && r <= R ) {
addedge ( v , o ) ;
return ;
}
int m = l + r >> 1 ;
if ( L <= m && T[o].l ) update ( L , R , v , T[o].l , l , m ) ;
if ( m < R && T[o].r ) update ( L , R , v , T[o].r , m + 1 , r ) ;
}
int tarjan ( int u ) {
dfn[u] = low[u] = ++ dfs_idx ;
S[top ++] = u ;
for ( int i = H[u] ; ~i ; i = E[i].n ) {
int v = E[i].v ;
if ( !dfn[v] ) low[u] = min ( low[u] , tarjan ( v ) ) ;
else if ( !scc[v] ) low[u] = min ( low[u] , dfn[v] ) ;
}
if ( low[u] == dfn[u] ) {
num[++ scc_cnt] = 0 ;
do {
scc[S[-- top]] = scc_cnt ;
if ( vis[S[top]] ) ++ num[scc_cnt] ;
} while ( S[top] != u ) ;
}
return low[u] ;
}
void solve () {
int x , y ;
init () ;
scanf ( "%d" , &n ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
G[i].clear () ;
}
for ( int i = 2 ; i <= n ; ++ i ) {
scanf ( "%d" , &x ) ;
G[x].push_back ( i ) ;
}
dep[1] = 1 ;
dfs ( 1 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%d%d" , &x , &y ) ;
update ( dep[x] , min ( dep[x] + y , n ) , idx[i] , root[x] , 1 , n ) ;
}
for ( int i = 1 ; i <= n ; ++ i ) if ( !dfn[i] ) {
tarjan ( i ) ;
}
LL ans = 0 ;
for ( int i = 1 ; i <= scc_cnt ; ++ i ) {
ans += 1LL * num[i] * ( num[i] - 1 ) / 2 ;
}
printf ( "%lld\n" , ans ) ;
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
for ( int i = 1 ; i <= T ; ++ i ) {
solve () ;
}
return 0 ;
}