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

 

posted @ 2015-02-09 22:25  idy002  阅读(151)  评论(0编辑  收藏