1 条题解

  • 0
    @ 2017-10-30 19:33:37

    /***************************************************
    * 查询两点是否连通,相当于查询两点之间是否有断点
    * 那么考虑树上差分,维护每个点到根节点的路径上,断点
    * 的个数,直接按照DFS序,用树状数组维护即可
    **************************************************/
    #include <iostream>
    #include <cstdio>
    #include <vector>
    using namespace std;
    const int maxn = 300300;
    const int maxm = 300300;
    int n, m, tot, coc, root;
    vector <int> G[ maxn ];
    struct BIT{
    int s[ maxn << 1 ];
    void add(int p,int v){
    for(int i = p ; i <= n << 1 ; i += i & (-i) )
    s[ i ] += v;
    }
    int query(int p){
    int rtn = 0;
    for(int i = p ; i ; i -= i & (-i) )
    rtn += s[ i ];
    return rtn;
    }
    }dis;

    int dep[ maxn ], son[ maxn ], fa[ maxn ], sz[ maxn ], top[ maxn ], pin[ maxn ], pout[ maxn ];
    int Q[ maxm ];
    void dfs1(int k){
    sz[ k ] = 1;
    for(int i = 0; i < G[ k ].size(); ++i){
    int kk = G[ k ][ i ];
    if( kk == fa[ k ] ) continue;
    fa[ kk ] = k;
    dep[ kk ] = dep[ k ] + 1;
    dfs1( kk );
    if( sz[ son[ k ] ] < sz[ kk ] ) son[ k ] = kk;
    sz[ k ] += sz[ kk ];
    }
    }
    void dfs2(int k, int t){
    top[ k ] = t;
    pin[ k ] = ++coc;
    if( !son[ k ] ) return ( void ) (pout[ k ] = ++coc);
    dfs2( son[k] , t );
    for(int i = 0; i < G[ k ].size(); ++i){
    int kk = G[ k ][ i ];
    if( kk == fa[ k ] || kk == son[ k ] )continue;
    dfs2( kk , kk );
    }
    return ( void ) (pout[ k ] = ++coc);
    }
    int lca(int x, int y){
    while( top[ x ] != top[ y ] ){
    if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap(x, y);
    x = fa[ top[ x ] ];
    }return dep[ x ] < dep[ y ] ? x : y;
    }
    struct io {
    char op[ 1 << 25 ] , *s;
    io(){
    //freopen("lct.in", "r", stdin);
    //freopen("lct.out", "w", stdout);
    fread( s = op , 1 , 1 << 25 , stdin );
    }

    int read(){
    int u = 0;
    while( *s < 48 || *s > 57 )s++;
    while( *s > 47 && *s < 58 )u = ( u << 1 ) + ( u << 3 ) + *s++ - 48;
    return u;
    }
    char gc(){
    while( *s < 'A' || *s > 'Z' )s++;
    return *s++ ;
    }
    }ip;
    #define read ip.read
    #define gcha ip.gc
    int main(){

    n = read(); m = read();
    for(int i = 1; i < n; ++i){
    int x = read() , y = read();
    G[ x ].push_back( y );
    G[ y ].push_back( x );
    }
    root = n / 2;
    dfs1( root );
    dfs2( root , root );
    for(int i = 1; i <= n; ++i){
    dis.add( pin[ i ], 1 );
    dis.add( pout[ i ],-1 );
    }
    while( m-- ){
    char s[5];
    int p, q, l, D1, D2;
    s[ 0 ] = gcha();
    switch( s[ 0 ] ){
    case 'Q': p = read(); q = read();
    l = lca( p , q );
    D1 = dep[ p ] + dep[ q ] - 2 * dep[ l ];
    D2 = dis.query( pin[ p ] ) + dis.query( pin[ q ] ) - 2 * dis.query( pin[ l ] );
    if(D1 == D2) printf("Yes\n"); else printf("No\n"); break;
    case 'C': p = read(); q = read();
    if(dep[ p ] < dep[ q ]) p = q;
    Q[ ++tot ] = p;
    dis.add( pin[ p ], -1 );
    dis.add( pout[ p ], 1 );
    break;
    case 'U': p = read();
    p = Q[ p ];
    dis.add( pin[ p ], 1 );
    dis.add( pout[ p ], -1 );
    break;
    }
    }
    return 0;
    }

  • 1

信息

难度
9
分类
(无)
标签
(无)
递交数
12
已通过
2
通过率
17%
上传者