题目分析:动态树果题= 3 =。。只有建边,修改单点权值,查询路径上的权值和操作。
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int MAXN = 30005 ;
struct Node* null ;
struct Node {
Node* c[2] ;
Node* f ;
int rev ;
int val ;
int sum ;
inline void newnode ( int value ) {
c[0] = c[1] = f = null ;
rev = 0 ;
val = sum = value ;
}
inline int is_root () {
return f == null || f->c[0] != this && f->c[1] != this ;
}
inline void setc ( Node* o , int d ) {
c[d] = o ;
o->f = this ;
}
inline void reverse () {
if ( this == null ) return ;
swap ( c[0] , c[1] ) ;
rev ^= 1 ;
}
inline void push_up () {
sum = c[0]->sum + val + c[1]->sum ;
}
inline void push_down () {
if ( rev ) {
c[0]->reverse () ;
c[1]->reverse () ;
rev = 0 ;
}
}
inline void sign_down () {
if ( !is_root () ) f->sign_down () ;
push_down () ;
}
inline void zig () {
Node* p = f ;
Node* g = f->f ;
p->setc ( c[1] , 0 ) ;
if ( !p->is_root () ) g->setc ( this , g->c[1] == p ) ;
else f = g ;
setc ( p , 1 ) ;
p->push_up () ;
}
inline void zag () {
Node* p = f ;
Node* g = f->f ;
p->setc ( c[0] , 1 ) ;
if ( !p->is_root () ) g->setc ( this , g->c[1] == p ) ;
else f = g ;
setc ( p , 0 ) ;
p->push_up () ;
}
inline Node* splay () {
sign_down () ;
while ( !is_root () ) {
if ( f->is_root () ) {
if ( this == f->c[0] ) zig () ;
else zag () ;
} else {
if ( f == f->f->c[0] ) {
if ( this == f->c[0] ) f->zig () , zig () ;
else zag () , zig () ;
} else {
if ( this == f->c[1] ) f->zag () , zag () ;
else zig () , zag () ;
}
}
}
push_up () ;
return this ;
}
inline Node* access () {
Node* o = this ;
Node* x = null ;
while ( o != null ) {
o->splay ()->setc ( x , 1 ) ;
o->push_up () ;
x = o ;
o = o->f ;
}
return splay () ;
}
inline void make_root () {
access ()->reverse () ;
}
inline Node* find_root () {
Node* o = access () ;
while ( o->c[0] != null ) {
o->push_down () ;
o = o->c[0] ;
}
return o ;
}
inline void link ( Node* o ) {
if ( o == this || find_root () == o->find_root () ) {
printf ( "no\n" ) ;
return ;
}
make_root () ;
f = o ;
printf ( "yes\n" ) ;
}
inline void change ( int value ) {
val = value ;
push_up () ;
splay () ;
}
inline void query ( Node* o ) {
if ( find_root () != o->find_root () ) {
printf ( "impossible\n" ) ;
return ;
}
make_root () ;
o->access () ;
printf ( "%d\n" , o->sum ) ;
}
} ;
Node pool[MAXN] ;
Node* cur ;
Node* node[MAXN] ;
int n , q ;
void clear () {
cur = pool ;
null = cur ++ ;
null->newnode ( 0 ) ;
}
void solve () {
char op[20] ;
int x , y ;
clear () ;
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%d" , &x ) ;
node[i] = cur ++ ;
node[i]->newnode ( x ) ;
}
scanf ( "%d" , &q ) ;
while ( q -- ) {
scanf ( "%s%d%d" , op , &x , &y ) ;
if ( op[0] == 'b' ) node[x]->link ( node[y] ) ;
else if ( op[0] == 'p' ) node[x]->change ( y ) ;
else node[x]->query ( node[y] ) ;
}
}
int main () {
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}