当前位置: 首页 > news >正文

并查集 D. Shark [Codeforces Round 484(Div. 2)]

一道还行的并查集,刚开始写的以为是带权并查集,写着写着发现其实不用太麻烦
题目大意是:需要找到一个值 k,使得数组中所有小于 k 的数字构成的连通块满足以下条件:

所有连通块的大小相同
连通块的数量尽可能多
在满足前两个条件下,k 的值尽可能小

如何寻找这个 k 呢?
二分显然不行,不满足单调性
那就直接从小到大枚举呗
每次枚举到一个数字,看看它前面后面是不是可以连起来
可以连起来就合并,使用并查集来维护连通块的大小
用map判断连通块大小及数量是否合格
然后扫一遍就做完了

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
#define ffp(x,y,z) for(ll (x)=(y);(x)<=(z);(x++))
#define ll long long int
#define q_ read()
inline ll read()
{ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch>'9'){if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();return x * f;
}void solve()
{int n = q_;vector<int>num(n + 2, 0);vector<int>id(n + 2, 0);vector<int>fa(n + 2, 0);vector<int>sz(n + 2, 0);//以i为根的子树的大小vector<bool>vis(n + 2, 0);map<int, int>ma;//判断答案用的ffp(i, 1, n){num[i] = q_;id[i] = i;fa[i] = i;sz[i] = 1;}auto cmp = [&](int a, int b)->bool{return num[a] < num[b];};sort(id.begin() + 1, id.end() - 1, cmp);auto find = [&](auto&& find, int a)->int{return a == fa[a] ? a : fa[a] = find(find, fa[a]);};int ans = num[id[1]];int lon = 0;ffp(i, 1, n){int x = id[i];//将这个位置的前面和后面连起来vis[x] = 1;sz[x] = 1;ma[sz[x]] += 1;int ba = find(find, min(x + 1, n));//找后一个,合并if (ba != x && vis[ba])//如果是没有出现过的数字,就别合并{ma[sz[x]]--;ma[sz[ba]]--;if (ma[sz[ba]] == 0)ma.erase(sz[ba]);if (ma[sz[x]] == 0)ma.erase(sz[x]);sz[x] += sz[ba];fa[ba] = x;ma[sz[x]]++;sz[ba] = 0;}int fr = find(find, max(x - 1, 1));//找前一个的根,看是谁if (fr != x && vis[fr]){//合并两根ma[sz[fr]] -= 1;ma[sz[x]] -= 1;if (ma[sz[fr]] == 0)ma.erase(sz[fr]);if (ma[sz[x]] == 0)ma.erase(sz[x]);sz[fr] += sz[x];fa[x] = fr;ma[sz[fr]]++;sz[x] = 0;}//记得判断是否删除了某个节点//合并后统计答案if (ma.size()==1){for (auto [v, cnt] : ma){if (cnt > lon){ans = num[x];lon = cnt;}}}}cout << ans+1 << endl;
}int main()
{int t = 1;while (t--){solve();}return 0;
}
http://www.zskr.cn/news/15284.html

相关文章:

  • Hackersdaddy ROUGE CTF 2025 完整解题记录
  • AI元人文系列:透明推理者——下一代大模型架构设计
  • 实用指南:【C语言】char * 、char [ ]、const char * 和 void *的使用以及区别
  • 实用指南:1、docker入门简介
  • 调试parlant的大模型配置,最终自己动手写了g4f的模块挂载 - 教程
  • unity面向组合开发二:EC的代码实践
  • airsim多无人机+无人车联合仿真辅导 - 教程
  • CSP-JF36
  • 【进入便捷的系统不解决问题】ubuntu开机出现‘系统出错且无法恢复。请联系系统管理员’
  • QOJ #8147. Math Exam 题解
  • 国庆梦熊集训做题记录
  • 兰博平台: 星云抽卡豪华版. 作者acc177
  • AT_abc315_f [ABC315F] Shortcuts
  • 问题表 - microsoft
  • 随想八
  • SolarWinds Web Help Desk远程代码执行漏洞分析
  • Aria2安装
  • 正则表达式学习
  • 神经网络之简单的标量何以表达模型的拟合能力 - 指南
  • 一篇文章入门RabbitMQ:基本概念与Java利用
  • PHP程序员要是基础不扎实,越学越吃力
  • 《电路基础》第七章学习笔记
  • LLM大模型:deepseek sparse attention是个啥?
  • 微信公众号推文添加附件方法,1分钟学会!支持word,excel,pdf等适合招聘,公告,申请表等
  • 2025国庆Day2
  • vue - 实战3 - 后端
  • P11983 [JOIST 2025] 展览会 3 题解
  • 黑客马拉松(Hackathon)
  • 推荐系统中损失函数梳理:从Pointwise到Listwise
  • how to download a websites favicon.ico