(交换使逆序对数为1+并查集)CF1768D Lucky Permutation

news/2024/10/4 19:44:22/文章来源:https://www.cnblogs.com/iscr/p/18275677

题意:

思路:
先从排好序的数组考虑:1,2,3,4,5,...n,如果交换相邻元素,必然使得逆序对数+1。
考虑先将乱序数组变成顺序数组,最后交换任意一对相邻元素即可。
将所有的i与\(p_{i}\)连边,最后形成若干个环,交换次数其实就是边数,也即点数-环数。并查集维护。
注意特殊情况:如果任意一对相邻元素处于同一个环中,可以不需要先变成顺序,再交换相邻元素,可以直接一步到位使得逆序对数为1。

code:

#include <bits/stdc++.h>
#include<bits/extc++.h>
using namespace __gnu_pbds;
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using PII = pair<i64, i64>;
const int inf = 0x3f3f3f3f;
const i64 INF = 0x3f3f3f3f3f3f3f3f;
#define Z cout << "\n"
#define lb lower_bound
#define ub upper_bound
#define D(x) cerr << #x << ": " << (x) << "\n"
#define DV(v) cerr<<#v<<": ";for(int i=0;i<(v).size();i++)cerr<<((v)[i])<<",";cerr<<"\n"
#if 0
#define int i64
#endif
struct DSU {vector<int> fa, siz;DSU() {}DSU(int n) { init(n); }void init(int n) { fa.resize(n); iota(fa.begin(), fa.end(), 0); siz.assign(n, 1); }int find(int x) { while (x != fa[x]) { x = fa[x] = fa[fa[x]]; }return x; }bool same(int x, int y) { return find(x) == find(y); }bool merge(int x, int y) { x = find(x); y = find(y); if (x == y) { return false; }siz[x] += siz[y]; fa[y] = x; return true; }int size(int x) { return siz[find(x)]; }
};
signed main() {ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);int t;cin >> t;while (t--) {int n;cin >> n;DSU dsu(n + 1);vector<int>a(n + 5);for (int i = 1; i <= n; i++)cin >> a[i], dsu.merge(i, a[i]);int x = 0;for (int i = 1; i <= n; i++) {if (dsu.find(i) == i)x++;}int ans = n - x;bool ok = 0;for (int i = 1; i <= n - 1; i++) {if (dsu.same(i, i + 1))ok = 1;}if (ok)ans--; else ans++;cout << ans << "\n";}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/733709.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C++ Primer] 开始

C++ Primer 第5版中英版电子版pdf开始 C++ Primer 第5版pdf中英版 夸克云盘 百度云盘 提取码:qrjn该系列记录了我在学习C++过程中经常会遗忘和混淆的相关操作语法,以备将来用到时方便查找。 加油吧!!!🙆

【MX-S1】梦熊周赛 提高组 1(同步赛)

【MX-S1】梦熊周赛 提高组 1(同步赛)\(T1\) luogu P10672 【MX-S1-T1】壁垒 \(100pts\)一个简单的结论:随着前缀长度的增长,出现的数字种类数每次只能增加 \(0\) 或 \(2\)。考虑构造时可以从这里下手。一种构造方案是这样的:优先让数字种类数增加 \(2\),即先将原先没有出…

vue学习笔记-2

1.模板语法 文本插值 <template><p>{{ msg }}</p><br/> <p>{{ num+1 }}</p><br/> <p>{{ ok?"yes":"no" }}</p> </template> <script> export default{data(){return{msg:"模板语…

Nginx 站点配置多目录管理

运维需求 在使用Nginx 对多个站点进行配置和运行维护时,如果将多个站点的配置都放在同一配置文件中,对于server 部分的调整,随着时间的推移,可能对应的配置变更是由不同的人员接手,不方便系统的部署和迁移。解决方案 为了解决这个问题,可以考虑使用include 块。用于指定加…

PNAS | 中国农大汪海团队实现转录调控序列的人工智能设计

近日,中国农业大学农学院汪海团队联合美国康奈尔大学、丹麦奥胡斯大学、北京大学现代农业研究院、坦桑尼亚农业科学院等单位在_PNAS在线发表了题为Modeling 0.6 million genes for the rational design of functional cis-regulatory variants and de novo design of cis-regu…

[C++ Primer] 关联容器

C++关联容器相关操作关联容器标准库提供了8个关联容器。类型map和multimap定义在头文件map中;set和multiset定义在头文件set中;无序容器则定义在头文件unordered_map和unordered_set中。pair标准库类型,定义在头文件utility中。关联容器额外的类型别名:关联容器insert操作:…

Kali 关闭自动锁屏功能

Kali 关闭自动锁屏功能 1、点击 [开始] -> [设置] -> [电源管理器]2、选择 [安全性],将 [自动锁定会话] 选为 [从不],将 [当系统休眠时锁定屏幕] 取消勾选,点击 [关闭]

键盘记录大师:用pynput轻松捕获每一个按键,包括组合键和功能键

哈喽,大家好,我是木头左!揭秘键盘输入的监控神器 - pynput库 在数字时代,键盘是与计算机交流的主要工具。无论是编写代码、撰写文档还是进行日常通讯,键盘的每一次敲击都承载着信息。而在某些场景下,可能需要记录这些信息,比如开发一个学习打字的软件、监控儿童的上网行…

word通用模板说明

个人偷懒,标题、表、图、公式按章节自动编号,字体与间距按照武汉理工大学硕士论文设置,方便平时报告用,模板在个人文件夹中https://files.cnblogs.com/files/blogs/806514/%E9%80%9A%E7%94%A8word%E6%A8%A1%E6%9D%BF.zip?t=1719659030&download=true 标题自动编号 点击…

HydroOJ 从入门到入土(20)已通过的题目显示 AC 代码

定期的代码汇总分析和整理是必要的。个人面板里,通过的题目,直接链接到对应的AC记录。用处就是可以按人汇总,便于学生自己整理,以及老师分析学生。 权限:看不了别人代码的人,依然看不了别人代码。 效果修改后端 进入 user.ts 文件 435 行左右: cd /usr/local/share/.con…