1 solutions

  • 0
    @ 2025-11-5 15:54:11

    C++ :

    #include<cstdio>
    #include<cstring>
    #define N 30010
     
    typedef struct MyStruct
    {
    	int father;//父亲结点
    	int total_num;//整棵树的结点总数
    	int up_num;//在当前结点之上的结点总数目
    }POINT;
     
    POINT point[N];
     
    int find_parent(int p)
    {
    	if (point[p].father==p)
    	{
    		return p;
    	}
    	else//路径压缩
    	{
    		int parent=point[p].father;
    		point[p].father=find_parent(point[p].father);
    		point[p].up_num+=point[parent].up_num;//更新每个结点其上结点的数目
    		return point[p].father;//层层递归,每次递归前,point[p].up_num都已经更新完毕
    	}
    }
     
    void makeup(int a,int b)//合并操作
    {
    	a=find_parent(a);
    	b=find_parent(b);
    	if (a!=b)
    	{
    		point[b].father=a;//将a的一堆放到b这堆上面来
    		point[b].up_num=point[a].total_num;//b堆顶元素的up_num就是a堆元素的总个数
    		//	这里注意,只需暂时更新树根结点b上的结点数目,所有b堆的子节点的数据会在之后的find_parent的迭代过程中更新!!注意!!
    		point[a].total_num+=point[b].total_num;//更新整颗树上的结点总数目,只对根节点有效,其余子节点上的此值为废值
    	}
     
    }
     
    int main()
    {
    	int n,p;//石块数和操作数
    	int i;
    	int a,b;//合并操作的两个堆
    	int k;//问k下面有多少块石块
    	int ans;
    	char temp;
    	for ( i = 1; i <N-1; i++)//初始化
    	{
    		point[i].father=i;
    		point[i].total_num=1;
    		point[i].up_num=0;
    	}
    	scanf("%d",&p);
    	for ( i = 1; i <=p ; i++)
    	{
    		getchar();
    		scanf("%c",&temp);
    		if (temp=='A')
    		{
    			scanf("%d%d",&a,&b);
    			makeup(b,a);//把含b的放到含a的上面
    		}
    		else
    		{
    			scanf("%d",&k);
    			ans=point[ find_parent(k) ].total_num - point[k].up_num -1;
    			printf("%d\n",ans);
    		}
    	}
    	return 0;
    }
    
    • 1

    Information

    ID
    17307
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    (None)
    Tags
    # Submissions
    0
    Accepted
    0
    Uploaded By