#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ls son[0][rt]
#define rs son[1][rt]
using namespace std ;
const int maxn = 211111 ;
int son[2][maxn] , fa[maxn] , is[maxn] , size[maxn] , rev[maxn] ;
void push_up ( int rt ) {
size[rt] = size[ls] + size[rs] + 1 ;
}
void reverse ( int rt ) {
if ( !rt ) return ;
swap ( ls , rs ) ;
rev[rt] ^= 1 ;
}
void push_down ( int rt ) {
if ( rev[rt] ) {
reverse ( ls ) ;
reverse ( rs ) ;
rev[rt] = 0 ;
}
}
void down ( int rt ) {
if ( !is[rt] ) down ( fa[rt] ) ;
push_down ( rt ) ;
}
void rot ( int rt , int c ) {
int y = fa[rt] , z = fa[y] ;
son[!c][y] = son[c][rt] ; fa[son[c][rt]] = y ;
son[c][rt] = y ; fa[y] = rt ;
fa[rt] = z ;
if ( is[y] ) is[y] = 0 , is[rt] = 1 ;
else son[y==son[1][z]][z] = rt ;
push_up ( y ) ;
}
void splay ( int rt ) {
down ( rt ) ;
while ( !is[rt] ) {
int y = fa[rt] , z = fa[y] ;
if ( is[y] ) rot ( rt , rt == son[0][y] ) ;
else {
int c = ( rt == son[0][y] ) , d = ( y == son[0][z] ) ;
if ( c == d ) rot ( y , c ) , rot ( rt , c ) ;
else rot ( rt , c ) , rot ( rt , d ) ;
}
}
push_up ( rt ) ;
}
void access ( int rt ) {
for ( int v = 0 ; rt ; rt = fa[rt] ) {
splay ( rt ) ;
is[rs] = 1 ; is[v] = 0 ;
rs = v ;
v = rt ;
push_up ( rt ) ;
}
}
void change_root ( int rt ) {
access ( rt ) ;
splay ( rt ) ;
reverse ( rt ) ;
}
int query ( int a , int b ) {
while ( fa[a] ) a = fa[a] ;
while ( fa[b] ) b = fa[b] ;
return a == b ;
}
void cut ( int a , int b ) {
if ( query ( a , b ) ) {
change_root ( a ) ;
access ( a ) ;
splay ( b ) ;
fa[b] = 0 ;
}
}
void add ( int a , int b ) {
if ( !query ( a , b ) ) {
splay ( b ) ;
fa[b] = a ;
}
}
void init ( int rt ) {
size[rt] = is[rt] = 1 ;
son[0][rt] = son[1][rt] = fa[rt] = rev[rt] = 0 ;
}
int num[maxn] ;
int main () {
int n , m , i , a , b , c ;
while ( scanf ( "%d" , &n ) != EOF ) {
for ( i = 1 ; i <= n + 1 ; i ++ ) init ( i ) ;
for ( i = 1 ; i <= n ; i ++ ) {
scanf ( "%d" , &a ) ;
num[i] = a ;
if ( i + a <= n ) add ( i + a , i ) ;
else add ( n + 1 , i ) ;
}
scanf ( "%d" , &m ) ;
while ( m -- ) {
scanf ( "%d%d" , &c , &a ) ;
a ++ ;
if ( c == 1 ) {
change_root ( n + 1 ) ;
access ( a ) ;
splay ( a ) ;
printf ( "%d\n" , size[son[0][a]] ) ;
}
else {
scanf ( "%d" , &b ) ;
int d = a + num[a] ; num[a] = b ;
cut ( a , min ( d , n + 1 ) ) ;
add ( min ( num[a] + a , n + 1 ) , a ) ;
}
}
}
return 0 ;
}2002: [Hnoi2010]Bounce 弹飞绵羊(link-cut-tree),布布扣,bubuko.com
2002: [Hnoi2010]Bounce 弹飞绵羊(link-cut-tree)
原文:http://blog.csdn.net/no__stop/article/details/21833499