您的位置:首页 > 其它

BZOJ 3282: Tree( LCT )

2015-06-25 14:15 423 查看


LCT..

--------------------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i )#define clr( x , c ) memset( x , c , sizeof( x ) ) using namespace std; const int maxn = 300000 + 5;const int maxnode = maxn + 100; int n; struct Node *pt , *null; struct Node { Node *ch[ 2 ] , *p , *fa; int v , x; bool rev , isRoot; Node( int _v = 0 ) : v( _v ) , x( _v ) { ch[ 0 ] = ch[ 1 ] = p = fa = null; rev = false; isRoot = true; } inline bool d() { return this == p -> ch[ 1 ]; } inline void setc( Node* c , int d ) { ch[ d ] = c; c -> p = this; } inline void relax() { if( rev ) { rev = false; rep( i , 2 ) if( ch[ i ] != null ) ch[ i ] -> Rev(); } } inline void Rev() { rev ^= 1; swap( ch[ 0 ] , ch[ 1 ] ); } inline void setRoot() { fa = p; p = null; isRoot = true; } inline void upd() { x = ch[ 0 ] -> x ^ v ^ ch[ 1 ] -> x; } void* operator new( size_t ) { return pt++; }}; Node NODE[ maxnode ]; void rot( Node* t ) { Node* p = t -> p; p -> relax(); t -> relax(); int d = t -> d(); p -> p -> setc( t , p -> d() ); p -> setc( t -> ch[ d ^ 1 ] , d ); t -> setc( p , d ^ 1 ); p -> upd(); if( p -> isRoot ) { p -> isRoot = false; t -> isRoot = true; t -> fa = p -> fa; }} void splay( Node* t , Node* f = null ) { static Node* S[ maxn ]; int top = 0; for( Node* o = t ; o != null ; o = o -> p ) S[ ++top ] = o; while( top ) S[ top-- ] -> relax(); for( Node* p = t -> p ; p != f ; p = t -> p ) { if( p -> p != f ) p -> d() != t -> d() ? rot( t ) : rot( p ); rot( t ); } t -> upd();} void access( Node* t ) { for( Node* o = null ; t != null ; o = t , t = t -> fa ) { splay( t ); t -> ch[ 1 ] -> setRoot(); t -> setc( o , 1 ); }} void makeRoot( Node* t ) { access( t ); splay( t ); t -> Rev();} Node* findRoot( Node* t ) { access( t ); splay( t ); for( ; t -> ch[ 0 ] != null ; t = t -> ch[ 0 ] ) t -> relax(); splay( t ); return t;} void join( Node* x , Node* y ) { makeRoot( x ); x -> fa= y; splay( y );} Node* get( Node* x , Node* y ) { makeRoot( x ); access( y ); splay( y ); return y;} void cut( Node* x , Node* y ) { makeRoot( x ); access( y ); splay( x ); x -> setc( null , 1 ); x -> upd(); y -> p = null; y -> setRoot();} void init() { pt = NODE; null = new Node( 0 );} Node* V[ maxn ]; int main() { freopen( "test.in" , "r" , stdin ); init(); int m; cin >> n >> m; rep( i , n ) { int v; scanf( "%d" , &v ); V[ i ] = new Node( v ); } int x , y , op; while( m-- ) { scanf( "%d%d%d" , &op , &x , &y ); x-- , y--; if( op == 3 ) { y++; access( V[ x ] ); splay( V[ x ] ); V[ x ] -> v = y; V[ x ] -> upd(); } else if( ! op ) { Node* t = get( V[ x ] , V[ y ] ); printf( "%d\n" , get( V[ x ] , V[ y ] ) -> x ); } else if( op == 1 ) { if( findRoot( V[ x ] ) != findRoot( V[ y ] ) ) join( V[ x ] , V[ y ] ); } else { if( findRoot( V[ x ] ) == findRoot( V[ y ] ) ) cut( V[ x ] , V[ y ] ); } } return 0;}

--------------------------------------------------------------------------------

3282: Tree

Time Limit: 30 Sec Memory Limit: 512 MB
Submit: 827 Solved: 341
[Submit][Status][Discuss]

Description

给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。

0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。

1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。

2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。

3:后接两个整数(x,y),代表将点X上的权值变成Y。

Input

第1行两个整数,分别为N和M,代表点数和操作数。

第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。

Output

对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

Sample Input

3 3
1
2
3
1 1 2
0 1 2
0 1 1

Sample Output

3
1

HINT

1<=N,M<=300000

Source

动态树
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: