首页 > 其他分享 >CF1768D Lucky Permutation Solution

CF1768D Lucky Permutation Solution

时间:2024-07-29 21:09:02浏览次数:13  
标签:排列 cin int CF1768D 交换 Solution Lucky fa 步数

CF1768D 题意不再简述。

首先题目要求变成逆序对只有一个的排列,也就是说,我们可以先考虑将一个排列通过交换元素变成另一个排列最小的步数,我们可以将两个排列相同位置上的数连边,很显然会形成几个环,若排列长度为 \(n\),形成 \(t\) 个环,每个环长为 \(len_i\),则每个环交换完至少是依次交换,也就是总共需要 \(\sum_{i=1}^t (len_i-1)=n-t\)。所以求出步数是 \(O(n)\) 的。

然后,题目要求变成的目标排列是逆序对只有一个,也就是目标排列是将升序排列中一对相邻元素交换后得到的,显然就有一个 \(O(n^2)\) 的算法:枚举交换的相邻元素,计算出步数然后取最小值。

然而这并不能过此题,考虑优化,我们交换操作至多会影响两个环,也就是说,我们先对原序列和生序序列之间处理出环,然后考虑交换的位置,设交换的两个位置是 \(i\) 和 \(i+1\),通过手玩可以发现:当 \(i\) 和 \(i+1\) 在同个环内时,交换操作会把这个环一分为二,总步数会减一;反之,当 \(i\) 和 \(i+1\) 在不同环内时,交换操作会把两个环合二为一,总步数加一。所以我们通过并查集维护是否在同环之内,先预处理出原序列与升序序列之间的环,然后考虑交换操作,\(O(1)\) 求出每次交换后总答案,最后取最小值,时间复杂度 \(O(n)\)。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 2e5 + 10;

int n, A[N], T[N], id[N], bel[N], fa[N], cnt[N];

int Find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = Find(fa[x]);
}

int main() {
	ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int _; cin >> _;
	while (_ --) {
		cin >> n;
		for (int i = 1; i <= n; i ++) {
			cin >> A[i]; fa[i] = i; cnt[i] = 1;
		}
		for (int i = 1; i <= n; i ++) {
			if (Find(A[i]) != Find(i)) {
				cnt[Find(i)] += cnt[Find(A[i])]; cnt[Find(A[i])] = 0;
				fa[Find(A[i])] = Find(i);
			}
		}
		int S = 0, Ans = 1e9;
		for (int i = 1; i <= n; i ++) 
			if (fa[i] == i) S += cnt[i] - 1;
		for (int i = 1; i < n; i ++) {
			if (Find(i) == Find(i + 1)) Ans = min(Ans, S - 1);
			else Ans = min(Ans, S + 1);
		}
		cout << Ans << "\n";
	}
	return 0;
} 

标签:排列,cin,int,CF1768D,交换,Solution,Lucky,fa,步数
From: https://www.cnblogs.com/LaDeX-Blog/p/18331059/CF1768D-sol

相关文章

  • Solution - Atcoder UTPC2023P Priority Queue 3
    考虑找一些关于合法的\(X\)加入的数的判定条件。假设遇到了一个\(\operatorname{pop}\)操作,令这里删除的数为\(a_i\),显然\(X\)中的数应该要有\(a_i\),其次\(X\)中其他的加入的数要么\(>a_i\)要么是\(a\)中的元素(在前面的\(\operatorname{pop}\)就已经被删了)。于......
  • Solution - Atcoder ABC280Ex Substring Sort
    对于这种子串问题,且有多个基础串,一个比较直观的想法就是先上个广义SAM。考虑SAM与字典序如何联系上。因为跳\(\operatorname{fail}\)相当于是删除子串的一个前缀,直接这样子明显是不行的,因为跳了\(\operatorname{fail}\)字典序没有一个很直观地表示。但是反过来考虑反串,......
  • Solution - Atcoder ARC114F Permutation Division
    令\(a\)为题目中的\(P\)。首先考虑后手的重排策略是什么。因为\(a\)是个排列,元素互不相同,那么肯定就是按照每一段的第一个数的大小,越大的放在越前面。那么当\(a_1\lek\)的时候,显然先手会把以\(1\simk\)开头来划分段。因为否则存在一个开头\(>k\)的段,后手把其放......
  • 【题解】Solution Set - 杂题选讲「刘君实」
    https://www.becoder.com.cn/contest/5423「HNOI2012」集合选数感觉差不多会。7/25sh杂题听课情况NOI2018冒泡排序【40】几乎不会麦田里的守望者【40】打表找规律、最后dp不太理解星空列车【40】完全不会WereYouLast:知道怎么做,但是不知道为什么是对的A......
  • solution - qoj8794
    (Un)labeledgraphs题解orzjiangly通信题。不禁让人想到。对于这道题目,考虑要还原原来的点的编号,而题目条件里有一个。还是非常明显,发现我们可以搞出一排新的点让它们构成一条新的链。然后第\(i\)个点往原图中编号为\(u\)的点连边,满足\(u\&2^{i-1}\)。现在我们需要......
  • AT_abc363_e [ABC363E] Sinking Land Solution
    题目大意:有一座矩形岛屿,被分为\(H\timesW\)的网格,四周与海水接触,给定时间\(Y\)年,最初海平面位于高度\(0\\text{m}\),每年海水上升\(1\\text{m}\),请求出每年未被海水淹没的格子数(高度小于等于海水高度即为淹没)。显然有点类似于广搜的想法,用一个队列存储与海水接触的方......
  • Solution - Atcoder Xmas2019E Sum of f(n)
    考虑\(F(n)=\sum\limits_{i=1}^nf_i=\sum\limits_{i=1}^n\sum\limits_{p\in\mathbb{P},k\ge1}[p^k|i]=\sum\limits_{p\in\mathbb{P},k\ge1}\lfloor\frac{n}{p^k}\rfloor\)。对于这个\(\lfloor\frac{n}{x}\rfloor\),一个比较经典的想法就是考虑对其......
  • Solution - Atcoder Xmas2019D Sum of (-1)^f(n).md
    对于\(f(i)=(-1)^{\sum\limits_jc_j}(i=\prod\limits_jp_j^{c_j}(p_j\in\mathbb{P}))\),一个比较特殊的值就是在\(i\in\mathbb{P}\)时有\(f(i)=-1\)。于是考虑PowerfulNumber筛,构造积性函数\(g\)使得对于\(i\in\mathbb{P}\)有\(g(p)=f(p)\)且\(g\)易......
  • Solution Set - 容斥原理/二项式反演
    https://www.becoder.com.cn/contest/5400「BZOJ2863」愤怒的元首题目就是求\(n\)个点DAG的数量。设\(dp_i\)表示\(i\)个点的DAG数量。首先DAG一定存在出度为\(0\)的点,其次删去出度为\(0\)的点,仍构成一个DAG。所以我们可以枚举删去的数量,从而划分子问题。......
  • [LeetCode] 1380. Lucky Numbers in a Matrix
    Givenanmxnmatrixofdistinctnumbers,returnallluckynumbersinthematrixinanyorder.Aluckynumberisanelementofthematrixsuchthatitistheminimumelementinitsrowandmaximuminitscolumn.Example1:Input:matrix=[[3,7,8],[9,11,......