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 }