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 MBSubmit: 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 31
2
3
1 1 2
0 1 2
0 1 1
Sample Output
31
HINT
1<=N,M<=300000Source
动态树相关文章推荐
- LAMP 马哥教程
- jar命令成功完成 java -jar 命令却提示“没有主清单属性”!
- 说说实际项目中如何防止重复提交
- Appium 并发和主从远程控制
- 字符串-03 字符串的冒泡排序(20)
- JVM常量池
- HackerRank - "Xor subsequence"
- hdu3466 Proud Merchants
- ng-repeat指令中使用track by子语句解决数据重复遍历的错误
- myeclipse10配置maven
- jQuery插件开发模式
- 65.输出单向链表中节点上最大值
- Substring with Concatenation of All Words 字符串操作 匹配的字串数
- 关于Code Review
- java泛型
- (总结)HTTP常见错误返回代码
- 关于easyui datebox的记录
- WPF中的TreeView如何定义模版,并绑定数据
- Android - Data Binding
- AngularJS+Servlet跨域问题