BZOJ 3282: Tree( LCT )

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 " , 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

原文地址:https://www.cnblogs.com/JSZX11556/p/4599858.html