题目链接:Gardener Bo
分情况处理add操作即可。
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std ;
typedef unsigned int UI ;
typedef pair < int , int > pii ;
#define clr( a , x ) memset ( a , x , sizeof a )
#define root 1 , 1 , n
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
const int MAXN = 300005 ;
const int MAXE = 300005 ;
struct Edge {
int v , n ;
Edge () {}
Edge ( int v , int n ) : v ( v ) , n ( n ) {}
} ;
Edge E[MAXE] ;
int H[MAXN] , cntE ;
int pre[MAXN] ;
int siz[MAXN] ;
int top[MAXN] ;
int dep[MAXN] ;
int pos[MAXN] ;
int out[MAXN] ;
int son[MAXN] ;
int cnt[MAXN] ;
int num[MAXN] ;
int tree_idx ;
int n , q ;
UI sum[MAXN << 2] ;
UI cnt_siz[MAXN] ;
UI add[MAXN] ;
UI w[MAXN] ;
UI f[MAXN] ;
void init () {
cntE = 0 ;
tree_idx = 0 ;
clr ( H , -1 ) ;
clr ( sum , 0 ) ;
}
void addedge ( int u , int v ) {
E[cntE] = Edge ( v , H[u] ) ;
H[u] = cntE ++ ;
}
void dfs ( int u ) {
siz[u] = 1 ;
son[u] = 0 ;
cnt[u] = 0 ;
num[u] = 0 ;
add[u] = 0 ;
cnt_siz[u] = 0 ;
for ( int i = H[u] ; ~i ; i = E[i].n ) {
int v = E[i].v ;
dep[v] = dep[u] + 1 ;
dfs ( v ) ;
cnt[u] ++ ;
cnt_siz[u] += ( UI ) ( cnt[v] + 1 ) * siz[v] ;
num[u] += cnt[v] + 1 ;
siz[u] += siz[v] ;
if ( siz[v] > siz[son[u]] ) son[u] = v ;
}
f[u] = w[u] * ( siz[u] + 1 ) ;
for ( int i = H[u] ; ~i ; i = E[i].n ) {
int v = E[i].v ;
w[u] += w[v] ;
f[u] += w[v] * ( siz[u] - siz[v] ) ;
}
}
void rebuild ( int u , int top_element ) {
top[u] = top_element ;
pos[u] = ++ tree_idx ;
if ( son[u] ) rebuild ( son[u] , top_element ) ;
for ( int i = H[u] ; ~i ; i = E[i].n ) {
int v = E[i].v ;
if ( v != son[u] ) rebuild ( v , v ) ;
}
out[u] = tree_idx ;
return ;
}
void Update ( int x , UI w ) {
while ( top[x] != top[1] ) {
int v = top[x] , u = pre[v] ;
f[u] += w * ( siz[u] - siz[v] ) ;
x = u ;
}
}
void update ( int x , UI v , int o , int l , int r ) {
sum[o] += v ;
if ( l == r ) return ;
int m = l + r >> 1 ;
if ( x <= m ) update ( x , v , lson ) ;
else update ( x , v , rson ) ;
}
UI query ( int L , int R , int o , int l , int r ) {
if ( L <= l && r <= R ) return sum[o] ;
int m = l + r >> 1 ;
if ( R <= m ) return query ( L , R , lson ) ;
if ( m < L ) return query ( L , R , rson ) ;
return query ( L , R , lson ) + query ( L , R , rson ) ;
}
void solve () {
init () ;
for ( int i = 2 ; i <= n ; ++ i ) {
scanf ( "%d" , &pre[i] ) ;
addedge ( pre[i] , i ) ;
}
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%u" , &w[i] ) ;
}
dfs ( 1 ) ;
rebuild ( 1 , 1 ) ;
while ( q -- ) {
int op , u ;
UI x ;
scanf ( "%d%d" , &op , &u ) ;
if ( op == 1 ) {
scanf ( "%u" , &x ) ;
add[u] += x ;
Update ( u , x * ( num[u] + 1 ) ) ;
update ( pos[u] , x * ( num[u] + 1 ) , root ) ;
} else {
UI ans = f[u] ;
int fa = pre[u] ;
ans += add[u] * siz[u] * num[u] + add[u] * ( siz[u] + 1 ) - add[u] * cnt_siz[u] ;
if ( fa ) {
int ga = pre[fa] ;
ans += add[fa] * cnt[u] * siz[u] + add[fa] * 2 ;
if ( ga ) ans += add[ga] * ( siz[u] + 1 ) ;
}
if ( son[u] ) ans += ( siz[u] - siz[son[u]] ) * query ( pos[son[u]] , out[son[u]] , root ) ;
printf ( "%u\n" , ans ) ;
}
}
}
int main () {
while ( ~scanf ( "%d%d" , &n , &q ) ) solve () ;
return 0 ;
}