Building Blocks

来源:互联网 发布:淘宝1块包邮的有什么 编辑:程序博客网 时间:2024/05/19 02:17

Problem Description

John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation: M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command. C X : Count the number of blocks under block X You are request to find out the output for each C operation.

Input

The first line contains integer P. Then P lines follow, each of which contain an operation describe above.

Output

Output the count for each C operations in one line.

Sample Input

6M 1 6C 1M 2 4M 2 6C 3C 4

Sample Output

102



想到用UF算法。因为砖块移动时,要把被移动砖块列最下面的砖块和要放的砖块列最上面的砖块找出来,就很好移动了。在两个数组里分别存放上面的砖块和下面的砖块的信息。

代码如下:
#includeusing namespace std;int N1[30000],N2[30000];//N1指向在X下面的砖块,N2指向在X上面的砖块;int U_blocks=0;int find1(int p){    U_blocks=0;    while (N1[p]!=0) {        p=N1[p];        U_blocks++; //统计下面砖块的个数    }    return p;}int find2(int p){    while (N2[p]!=0)        p=N2[p];    return p;}void move(int p,int t){    if (N1[p]!=0)//找出要移动的两排砖块里最下面的和最上面的砖块。        p=find1(p);    if (N2[t]!=0)        t=find2(t);    N1[p]=t;    N2[t]=p;}int main(){    memset(N1, 0,sizeof(N1));    memset(N2, 0, sizeof(N2));    char o;    int test;    cin>>test;    while (test--) {        cin>>o;        if (o=='M') {            int x,y;            cin>>x>>y;            move(x,y);        }        if (o=='C') {            int x;            cin>>x;            find1(x);            cout<