zcmu-1930帽子戏法

Description

小A家有很多很多顶帽子初始时帽子都是独立分开的,每顶帽子都有一个编号用于区分.小A会有以下操作之一:
1.将编号为y的帽子所在的帽子堆放在编号为x的帽子所在的帽子堆顶上,如果x,y在同一堆则不做任何动作.
2.小A会向你询问编号为x的帽子上方有多少只帽子.

Input

输入有多组数据:
第一行输入N,M分别为帽子数和操作数(1<=N<=40000,1<=M<=400000)
帽子的编号对应1,2,3...,N.
接下来有M行输入为 T x y 对应操作1. Q x 对应操作2.

Output

对于小A的询问输出位于编号为x的帽子上方的帽子数.

Sample Input

2 2

T 1 2

Q 1

Sample Output

1

用三个数组分别存放编号,数量,位置,然后fing查找(类似并查集)确定每个帽子上面的帽子数量

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int maxn=40005;
int a[maxn],b[maxn],c[maxn];
int n,m,x,y;
char str[5];
int find(int x)
{
    if(x!=a[x])
    {
        int X=a[x];
        a[x]=find(a[x]);
        b[x]+=b[X];
    }
    return a[x];
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
        {
            a[i]=i;
            b[i]=0;
            c[i]=1;
        }
        while(m--)
        {
            scanf("%s %d",str,&x);
            if(str[0]=='T')
            {
                scanf("%d",&y);
                int q=find(x),z=find(y);
                if(q==z) continue;
                a[q]=z;
                b[q]=c[z];
                c[z]+=c[q];
            }
            else
            {
                find(x);
                printf("%d\n",b[x]);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41058467/article/details/82971263