树链剖分模板
DFS1
void DFS1( int x , int f , int deep ) {
fa[x] = f ;
dep[x] = deep ;
Size[x] = 1 ;
for( int i = 0 ; i < G[x].size() ; ++ i ) {
int s = G[x][i] ;
if( s == f )
continue;
DFS1( s,x,deep+1 );
Size[x] += Size[s] ;
if( Size[s] > Size[son[x]] || !son[x] )
son[x] = s ;
}
}
DFS2
void DFS2( int x , int T ) {
top[x] = T ;
cnt ++ ;
id[x] = cnt ;
be[cnt] = x ;
if( !son[x] )
return ;
DFS2( son[x] , T );
for( int i = 0 ; i < G[x].size() ; ++ i ) {
int s = G[x][i] ;
if( s == son[x] || s == fa[x] )
continue ;
DFS2(s,s);
}
}
LCA
int Get_sum( int x , int y ) {
while( top[x] != top[y] ) {
if( dep[top[x]] < dep[top[y]] )
swap(x,y) ;
x = fa[top[x]] ;
}
if( dep[x] < dep[y] )
swap(x,y) ;
return y ;
}
LCA树剖模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#define N 100005
using namespace std ;
int n , m , ans ;
int dep[N] , fa[N] , son[N] , Size[N] ;
int top[N] , id[N] , be[N] , cnt ;//id为点x的DFS序,be为DFS序对应的点
vector <int> G[N] ;
struct node {
int l , r , sum ;
int lazy ;
} Tree[4*N] ;
void pushup( int x ) {//更新
int lson = 2*x , rson = 2*x+1 ;
Tree[x].sum = Tree[lson].sum + Tree[rson].sum ;
}
void pushdown( int x ) {//下放懒标记
if( Tree[x].lazy == 1 ) {
Tree[x].lazy = 0 ;
Tree[x*2].sum = Tree[x*2].r-Tree[x*2].l+1 ;
Tree[x*2+1].sum = Tree[x*2+1].r-Tree[x*2+1].l+1 ;//更新左右儿子
Tree[x*2].lazy = Tree[x*2+1].lazy = 1 ;
return ;
}
if( Tree[x].lazy == 2 ) {
Tree[x].lazy = 0 ;
Tree[x*2].sum = Tree[x*2+1].sum = 0 ;//更新左右儿子
Tree[x*2].lazy = Tree[x*2+1].lazy = 2 ;
}
}
void build( int l, int r , int x ) {//建线段树
if( l == r ) {
Tree[x].lazy = 0 ;
Tree[x].l = Tree[x].r = l ;
Tree[x].sum = 0 ;
return ;
}
Tree[x].sum = 0 , Tree[x].lazy = 0 ;
Tree[x].l = l , Tree[x].r = r ;
int mid = (l+r)/2 ;
build(l,mid,x*2);
build(mid+1,r,x*2+1);
pushup(x) ;
}
int quary1( int l , int r , int x ) {//下载
if( l > r )
swap(l,r) ;
if( l <= Tree[x].l && r >= Tree[x].r ) {
int sum = Tree[x].sum ;
Tree[x].sum = Tree[x].r-Tree[x].l+1 ;//下载赋值
Tree[x].lazy = 1 ;//懒标记
return sum ;
}
int mid = (Tree[x].l+Tree[x].r)/2 ;
pushdown(x) ;//下放懒标记
int sum = 0 ;
if( l <= mid )
sum += quary1(l,r,x*2) ;
if( r >= mid+1 )
sum += quary1(l,r,2*x+1) ;
pushup(x) ;//更新
return sum ;
}
int quary2( int l , int r , int x ) {//卸载
if( l > r )
swap(l,r) ;
if( l <= Tree[x].l && r >= Tree[x].r ) {
int sum = Tree[x].sum ;
Tree[x].sum = 0 ;//卸载清零
Tree[x].lazy = 2 ;//懒标记
return sum ;
}
int mid = (Tree[x].l+Tree[x].r)/2 ;
pushdown(x);//下放懒标记
int sum = 0 ;
if( l <= mid )
sum += quary2(l,r,x*2) ;
if( r >= mid+1 )
sum += quary2(l,r,2*x+1) ;
pushup(x) ;//更新
return sum ;
}
void DFS1( int x , int f , int deep ) {
fa[x] = f ;
dep[x] = deep ;
Size[x] = 1 ;
for( int i = 0 ; i < G[x].size() ; ++ i ) {
int s = G[x][i] ;
if( s == f )
continue;
DFS1( s,x,deep+1 );
Size[x] += Size[s] ;
if( Size[s] > Size[son[x]] || !son[x] )
son[x] = s ;
}
}
void DFS2( int x , int T ) {
top[x] = T ;
cnt ++ ;
id[x] = cnt ;
be[cnt] = x ;
if( !son[x] )
return ;
DFS2( son[x] , T );
for( int i = 0 ; i < G[x].size() ; ++ i ) {
int s = G[x][i] ;
if( s == son[x] || s == fa[x] )
continue ;
DFS2(s,s);
}
}
int Get_sum( int x , int y ) {
int sum = 0 ;
while( top[x] != top[y] ) {
if( dep[top[x]] < dep[top[y]] )
swap(x,y) ;
sum += quary1( id[x],id[top[x]],1 );
x = fa[top[x]] ;
}
sum += quary1( id[x],id[y],1 );
return sum ;
}
int main() {
scanf("%d", &n );
for( int i = 1 ; i < n ; ++ i ) {
int x ;
scanf("%d", &x );
G[i].push_back(x) ;
G[x].push_back(i) ;
}
cnt = 0 ;
DFS1(0,-1,1);
DFS2(0,0) ;
build(1,n,1);
scanf("%d", &m );
while( m -- ) {
string Fuck ;
cin >> Fuck ;
int x ;
scanf("%d", &x );
if( Fuck[0] == 'i' ) {
ans = Get_sum(x,0);
printf("%d\n", dep[x]-ans );
}
else {
ans = quary2( id[x] , id[x]+Size[x]-1 , 1 );
printf("%d\n", ans ) ;
}
}
}