您的位置:首页 > 其它

bzoj 2002 LinkCutTree

2015-02-09 22:25 387 查看
我的第一道LCT题(居然1A,O(∩_∩)O哈哈~)

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

大概题意:

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

题解:

Link Cut Tree

/**************************************************************
Problem: 2002
User: idy002
Language: C++
Result: Accepted
Time:1644 ms
Memory:5984 kb
****************************************************************/

#include <cstdio>
#include <iostream>
#define maxn 200010
using namespace std;

struct LCT {
int pre[maxn], son[maxn][2], siz[maxn];
int pnt[maxn];

void init( int n ) {
for( int i=1; i<=n; i++ ) {
int nd = i;
pre[nd] = son[nd][0] = son[nd][1] = 0;
pnt[nd] = 0;
siz[nd] = 1;
}
}
void update( int nd ) {
siz[nd] = siz[son[nd][0]]+siz[son[nd][1]]+1;
}
void rotate( int nd, int d ) {
int p = pre[nd];
int s = son[nd][!d];
int ss = son[s][d];

son[nd][!d] = ss;
son[s][d] = nd;
if( p ) son[p][ nd==son[p][1] ] = s;

pre[nd] = s;
pre[s] = p;
if( ss ) pre[ss] = nd;

if( pnt[nd] ) {
pnt[s] = pnt[nd];
pnt[nd] = 0;
}

update( nd );
update( s );
}
void splay( int nd, int top ) {
while( pre[nd]!=top ) {
int p = pre[nd];
int nl = nd==son[p][0];
if( pre[p]==top ) {
rotate( p, nl );
} else {
int pp = pre[p];
int pl = p==son[pp][0];
if( nl==pl ) {
rotate( pp, pl );
rotate( p, nl );
} else {
rotate( p, nl );
rotate( pp, pl );
}
}
}
}
void cut( int fa ) {
int s = son[fa][1];
if( s ) {
son[fa][1] = 0;
pre[s] = 0;
pnt[s] = fa;
}
}
void con( int sn ) {
int fa = pnt[sn];
pnt[sn] = 0;
son[fa][1] = sn;
pre[sn] = fa;
}
void access( int nd ) {
splay( nd, 0 );
cut( nd );
while( pnt[nd] ) {
splay( pnt[nd], 0 );
cut(pnt[nd]);
con(nd);
splay( nd, 0 );
}
}
void cuttree( int nd ) {
access( nd );
pre[ son[nd][0] ] = 0;
son[nd][0] = 0;
}
void contree( int nd, int fa ) {
access( nd );
pnt[nd] = fa;
access( nd );
}
int getdeep( int nd ) {
access( nd );
return siz[son[nd][0]];
}
};

int n, m;
int a[maxn];
LCT LT;
int main() {
scanf( "%d", &n );
LT.init(n+1);
for( int i=1,w; i<=n; i++ ) {
scanf( "%d", &w );
int fa = min( i+w, n+1 );
LT.contree( i, fa );
}
scanf( "%d", &m );
for( int i=1,opt,x,y; i<=m; i++ ) {
scanf( "%d", &opt );
if( opt==1 ) {  //  query
scanf( "%d", &x );
x++;
printf( "%d\n", LT.getdeep( x ) );
} else {
scanf( "%d%d", &x, &y );
x++;
int oldf = min( x+a[x], n+1 );
int newf = min( x+y, n+1 );
if( oldf==newf ) continue;
a[x] = y;
LT.cuttree( x );
LT.contree( x, newf );
}
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: