P8686 洛谷 修改数组

P8686 原题链接

做完这题感觉可以很好地理解并查集。

一眼看过去是不是只看出了暴力(不会只有我这样吧),我们先从暴力的方法再推到并查集方法,首先暴力的做法肯定是:如果一个数有重复的数那就一直加直到没有重复的数。

那这个过程能不能 \(O(1)\) 地求呢,当然可以,对于每个数 \(x\) 将他们的 \(fa[x]\) 一开始设为 \(x\) ,当遍历到这个点时,就将他的 \(fa[x]=x+1\) ,这样操作就可以使下一次遍历到这个点的时候就直接读取 \(fa[x]\) 就相当于 \(O(1)\) 地很好地避免重复增加。

这样一看,这并查集还真有点意思!

#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int n;
int a[N+5];
int fa[N+5];
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=N;i++){
fa[i]=i;
}
for(int i=1;i<=n;i++){
int x=find(a[i]);
cout<<x<<" ";
fa[x]++;
}
return 0;
}
posted @   sad_lin  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示