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 }

时间: 2024-07-28 12:56:52

bzoj 2002 LinkCutTree的相关文章

bzoj 2002

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3848  Solved: 2051[Submit][Status] Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki

lct 模版题 bzoj 2002 2049

很早就有人给我推荐的模版题,然后我最近才刷的(' '    ) 昨天的tree 不知道比他们高到哪里去了,我和他谈笑风生啊! bzoj 2002 弹飞绵羊 重点:这道题的cut和link 由于这道题链的特殊性所以不能用提根的方法搞,可以注意到每一次cut位置一定是前面的一个元素,所以access 上去之后直接把左边的儿子丢掉就行了(我原来的cut 是在不知道两个点的儿子关系时就强行提根(' '    )) 然后link的时候直接把cut的那一棵splay接过去就行了 1 #include <io

[BZOJ 2002][Luogu 3203][HNOI2010]Bounce 弹飞绵羊

[BZOJ 2002][Luogu 3203][HNOI2010]Bounce 弹飞绵羊 <题意概括> 给定一个数列$\left\{k_{N}\right\}$,数列长度为n,有k次操作 要求支持两种操作 1.求最少对数x进行几次变换才能满足条件$x>n$(一次操作定义为$x=x+k_{x}$) 2.将$k_{x}$修改为a <做法> 通过建模我们可以将题目转化为如下的问题 建一个图,将图中每个顶点i和顶点$i+k_{i}$连边 那么操作一就转化为了求顶点i到任一编号大于n的

BZOJ 2002 Bounce 弹飞绵羊(分块|暴力|)(困难)

Bounce 弹飞绵羊 Time Limit:10000MS     Memory Limit:265216KB     64bit IO Format:%lld & %llu Submit Status Practice HYSBZ 2002 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后

BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊( LCT )

LCT... ---------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #define clr( x , c ) memset( x

BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块

http://www.lydsy.com/JudgeOnline/problem.php?id=2002 维护cnt[i]表示第i个节点,跳出他所属于的块的最小步数, to[i]表示第i个节点,跳出他所属的块的时候,去到那一个位置. 那么, 查询:复杂度O(sqrt(n)),不断   ans += cnt[i]   然后   i  = to[i]即可. 更新:分块这种东西,跟新都是块内更新的,块间都是独立的. 更新第id个东西,可以知道是不影响后面的.而且如果我知道第id个跳去了那个块,步数也可

bzoj 2002 Bounce 弹飞绵羊(分块)

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 11202  Solved: 5698[Submit][Status][Discuss] Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹k

BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊(分块)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2002 [题目大意] 给出一片森林,操作允许更改一个节点的父亲,查询一个节点的深度. 父亲节点的编号一定大于子节点 [题解] 我们将所有的节点按照序号分块,记录其到下一个分块的深度, 以及其可以跳到下一个分块的位置, 那么修改节点的父亲对于所存储的数据的影响就被缩小到一个块内,单次修改sqrt(n). 动态树做法:链接 [代码] #include <cstdio> #include

分块 (貌似能用LCT做,反正我现在还不会) BZOJ 2002

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 9844  Solved: 5070[Submit][Status][Discuss] Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki