标签:vector ons 大小 parallel its 排序 sig clu ++
给定一个 \(n(n \le 10^5)\),然后长度为 \(n\) 的全排列 \(a\)。每次可以交换任意组(一组两个数,两两交换,不重复)的数。问最少交换多少轮能将整个排列排序。
排列/置换相关问题想象成 \(i \to p_i\) 的图
对于一个 \(len=2\) 的环,一次可以破掉
对于一个 \(len \ge 3\) 的环,一次好像破不掉……
但是对于环 \(p_1p_2...p_kp_1\),我们交换 \(p_1 - p_k, p_2 - p_{k-1}, ...\)
这样做一次后,最大的环大小不超过 \(2\),因此,对于任意情况,操作次数不会超过 \(2\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int n;
int p[N];
int v[N];
signed main()
{
ios::sync_with_stdio(false);
cin >> n;
vector<int> ans[2];
for (int i = 1; i <= n; i++)
cin >> p[i];
for (int _ = 0; _ < 2; _++)
{
memset(v, 0, sizeof v);
for (int i = 1; i <= n; i++)
{
if (v[i])
continue;
if (i == p[i])
continue;
int t = p[i];
vector<int> cyc;
cyc.push_back(i);
v[i] = 1;
while (t != i)
cyc.push_back(t), v[t] = 1, t = p[t];
for (int j = 0; j < cyc.size() / 2; j++)
{
int x = cyc[j], y = cyc[cyc.size() - 1 - j];
ans[_].push_back(x);
ans[_].push_back(y);
swap(p[x], p[y]);
}
}
}
if (ans[0].size() == 0)
{
cout << 0 << endl;
}
else if (ans[1].size() == 0)
{
cout << 1 << endl;
cout << ans[0].size() / 2 << " ";
for (auto i : ans[0])
cout << i << " ";
cout << endl;
}
else
{
cout << 2 << endl;
cout << ans[0].size() / 2 << " ";
for (auto i : ans[0])
cout << i << " ";
cout << endl;
cout << ans[1].size() / 2 << " ";
for (auto i : ans[1])
cout << i << " ";
cout << endl;
}
}
[ICPC2020昆明J] Parallel Sort - 构造
标签:vector ons 大小 parallel its 排序 sig clu ++
原文地址:https://www.cnblogs.com/mollnn/p/14622840.html