zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    【转】字典转模型需要注意的问题,以及第三方框架来处理字典转模型
    【转】使用SOAP访问Web服务
    Foundation框架2
    Foundation框架1
    什么是Protocol
    什么是Block
    什么么是Category
    ARC
    autorelease简介
    循环retain
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4599858.html
Copyright © 2011-2022 走看看