现在有一排n(n<=300000)个积木,按顺序从1到n编号,我们想把这些积木堆起来。
刚开始的时候,n个积木每一个是单独的柱子,接下来我们会进行m次操作,把这些积木堆成更高的柱子。
有两种操作类型:
1.将x好积木所在的柱子按照原顺序堆到y号积木所在的柱子上面
2.计算x号积木所在的柱子当中,堆在x积木之下的积木个数
Input
第一行一个正整数m,不会给出n的值
接下来m行,每行描述一个操作,如果这一行以M开头,那么接下来两个正整数x,y表示进行一次操作1;如果以C开头,接下来一个正整数x,表示进行一次操作2。
Output
输出若干行,表示每一次操作2的答案
Constraints
对于40%的数据 m<200
对于100%的数据 m<100000
一眼看出并查集(不解释)
洛谷有一道很相似的题目:银河英雄传说
我们每次进行操作1,将x与y所在的并查集合并
操作2输出x下的积木个数
在这中间进行一些处理就好了(好像什么也没说)
在上课没时间好好写注释了(っ•?ω•?)っ??? 我爱学习
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<queue> using namespace std; const int maxn=30010; int pre[maxn]; int m; int deep[maxn]; int under[maxn]; int findpa(int a) { if(pre[a]==a) return a; int fa=findpa(pre[a]); under[a]+=under[pre[a]]; return pre[a]=fa; } void step1(int x,int y){ int xx=findpa(x); int yy=findpa(y); if(xx==yy) return; under[xx]+=deep[yy]; deep[yy]+=deep[xx]; deep[xx]=0; pre[xx]=yy; return; } void step2(int x) { int xx=findpa(x); cout<<under[x]<<endl; } void read(){ for(int i=1;i<=maxn;i++) pre[i]=i,under[i]=0,deep[i]=1; cin>>m; for(int i=1;i<=m;i++) { int x,y; char c; cin>>c; if(c==‘M‘) {cin>>x>>y;step1(x,y);} if(c==‘C‘) {cin>>x;step2(x);} } } int main(){ //freopen("cubes.in","r",stdin); //freopen("cubes.out","w",stdout); read(); return 0; }
原文地址:https://www.cnblogs.com/cheng-qing/p/9734723.html
时间: 2024-11-02 21:18:42