• bzoj 2002 LinkCutTree


    我的第一道LCT题(居然1A,O(∩_∩)O哈哈~)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2002

    大概题意:

    给一颗有根树,维护每个节点的深度(到根节点的边数),支持断开子树并把它连接到任意节点。

    题解:

    Link Cut Tree

      1 /**************************************************************
      2     Problem: 2002
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:1644 ms
      7     Memory:5984 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <iostream>
     12 #define maxn 200010
     13 using namespace std;
     14  
     15 struct LCT {
     16     int pre[maxn], son[maxn][2], siz[maxn];
     17     int pnt[maxn];
     18  
     19     void init( int n ) {
     20         for( int i=1; i<=n; i++ ) {
     21             int nd = i;
     22             pre[nd] = son[nd][0] = son[nd][1] = 0;
     23             pnt[nd] = 0;
     24             siz[nd] = 1;
     25         }
     26     }
     27     void update( int nd ) {
     28         siz[nd] = siz[son[nd][0]]+siz[son[nd][1]]+1;
     29     }
     30     void rotate( int nd, int d ) {
     31         int p = pre[nd];
     32         int s = son[nd][!d];
     33         int ss = son[s][d];
     34  
     35         son[nd][!d] = ss;
     36         son[s][d] = nd;
     37         if( p ) son[p][ nd==son[p][1] ] = s;
     38  
     39         pre[nd] = s;
     40         pre[s] = p;
     41         if( ss ) pre[ss] = nd;
     42          
     43         if( pnt[nd] ) {
     44             pnt[s] = pnt[nd];
     45             pnt[nd] = 0;
     46         }
     47  
     48         update( nd );
     49         update( s );
     50     }
     51     void splay( int nd, int top ) {
     52         while( pre[nd]!=top ) {
     53             int p = pre[nd];
     54             int nl = nd==son[p][0];
     55             if( pre[p]==top ) {
     56                 rotate( p, nl );
     57             } else {
     58                 int pp = pre[p];
     59                 int pl = p==son[pp][0];
     60                 if( nl==pl ) {
     61                     rotate( pp, pl );
     62                     rotate( p, nl );
     63                 } else {
     64                     rotate( p, nl );
     65                     rotate( pp, pl );
     66                 }
     67             }
     68         }
     69     }
     70     void cut( int fa ) {
     71         int s = son[fa][1];
     72         if( s ) {
     73             son[fa][1] = 0;
     74             pre[s] = 0;
     75             pnt[s] = fa;
     76         }
     77     }
     78     void con( int sn ) {
     79         int fa = pnt[sn];
     80         pnt[sn] = 0;
     81         son[fa][1] = sn;
     82         pre[sn] = fa;
     83     }
     84     void access( int nd ) {
     85         splay( nd, 0 );
     86         cut( nd );
     87         while( pnt[nd] ) {
     88             splay( pnt[nd], 0 );
     89             cut(pnt[nd]);
     90             con(nd);
     91             splay( nd, 0 );
     92         }
     93     }
     94     void cuttree( int nd ) {
     95         access( nd );
     96         pre[ son[nd][0] ] = 0;
     97         son[nd][0] = 0;
     98     }
     99     void contree( int nd, int fa ) {
    100         access( nd );
    101         pnt[nd] = fa;
    102         access( nd );
    103     }
    104     int getdeep( int nd ) {
    105         access( nd );
    106         return siz[son[nd][0]];
    107     }
    108 };
    109  
    110 int n, m;
    111 int a[maxn];
    112 LCT LT;
    113 int main() {
    114     scanf( "%d", &n );
    115     LT.init(n+1);
    116     for( int i=1,w; i<=n; i++ ) {
    117         scanf( "%d", &w );
    118         int fa = min( i+w, n+1 );
    119         LT.contree( i, fa );
    120     }
    121     scanf( "%d", &m );
    122     for( int i=1,opt,x,y; i<=m; i++ ) {
    123         scanf( "%d", &opt );
    124         if( opt==1 ) {  //  query
    125             scanf( "%d", &x );
    126             x++;
    127             printf( "%d
    ", LT.getdeep( x ) );
    128         } else {
    129             scanf( "%d%d", &x, &y );
    130             x++;
    131             int oldf = min( x+a[x], n+1 );
    132             int newf = min( x+y, n+1 );
    133             if( oldf==newf ) continue;
    134             a[x] = y;
    135             LT.cuttree( x );
    136             LT.contree( x, newf );
    137         }
    138     }
    139 }
    View Code
  • 相关阅读:
    C++中的模板编程
    C++中的抽象类
    C++中的多态
    C++中的继承
    操作符重载(二)
    操作符重载(一)
    C++中的类与对象模型
    [八省联考2018] 劈配 (网络流+二分)
    CF51F Caterpillar (边双+树形DP)
    CF36E Two Paths (欧拉回路+构造)
  • 原文地址:https://www.cnblogs.com/idy002/p/4282644.html
Copyright © 2020-2023  润新知