BZOJ3367 带权并查集

来源:互联网 发布:淘宝客服要交保证金吗 编辑:程序博客网 时间:2024/06/06 16:16

大家都很强,可与之共勉 。

Link

Description

约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.

游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种:
1.移动(M):将包含X的立方柱移动到包含Y的立方柱上.
2.统计(C):统计名含X的立方柱中,在X下方的方块数目.
写个程序帮贝茜完成游戏.
Input

第1行输入P,之后P行每行输入一条指令.形式为“M X Y”或者“C X”输入保证不会有将立方柱放在自己头上的指令.

Output

每一行,对于每个统计指令,输出其结果.

Sample Input

6

M 1 6

C 1

M 2 4

M 2 6

C 3

C 4
Sample Output

1

0

2

题解

编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.
有P(1≤P≤100000)个指令.指令有两种:
1.移动(M):将包含X的立方柱移动到包含Y的立方柱上.
2.统计(C):统计名含X的立方柱中,在X下方的方块数目.
题解:
带权并查集
存三个东西,x所在立方柱的最顶端fa[x],x所在立方柱的最底端d[x],x上面有多少个立方柱val[x]。

那么要求的x下方的数目就可以用val[d[x]]-val[x]来表示。

记得查的时候要更新哦!!!

/**************************************************************    Problem: 3376    User: Lazer2001    Language: C++    Result: Accepted    Time:172 ms    Memory:1172 kb****************************************************************/# include <cstdio>int fa [30005], val [30005], d [30005] ;inline int find ( int x )  {    if ( x ^ fa [x] )  {        int y = fa [x] ;        fa [x] = find ( y ) ;        val [x] += val [y] ;        d [x] = d [y] ;    }    return fa [x] ;}int main ( )  {    register int P, c, x, y, fx, fy ;    scanf ( "%d", & P ) ;    for ( register int i = 1 ; i <= 30000 ; ++ i  )  d [i] = i ;    for ( register int i = 1 ; i <= 30000 ; ++ i  )  fa [i] = i ;    while ( P -- )  {        while ( ( c = getchar ( ) ) == ' ' || c == '\n' ) ;        if ( c ^ 'C' )  {            scanf ( "%d%d", & x, & y ) ;            fx = find ( x ), fy = find ( y ) ;            fa [fy] = fx ;            val [fy] = val [d [fx]] + 1 ;             d [fx] = d [fy] ;            find ( d [x] ) ; find ( d [y] ) ;            continue ;        }        scanf ( "%d", & x ) ;        find ( x ) ;        printf ( "%d\n", val [d [x]] - val [x] ) ;    }}
原创粉丝点击