版权声明:_ https://blog.csdn.net/lunch__/article/details/82085085
题目链接
这个题 有点小恶心啊… 各种要判的东西都没判
先搬
的题解…
如果看懂了把若干个环两次排序解决的方法 接下来的就比较简单了
首先判
错位个数大于操作下标数即无解‘
然后判
错位个数为
即答案为
我们对于离散后的每一个值开个 把每个元素最后应该到的位置的下标存进去,然后 把这若干个环存下来
然后又到了特判时间
如果可操作次数减去不在原位置的数只剩下
就直接暴力拆所有环就够了…
剩下的情况 如果环的个数大于可操作次数
那就暴力拆环拆到环的个数等于可操作次数
然后再用那个两次排序的方法解决就好了 实现起来有点恶心看代码把
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N = 2e5 + 10;
vector<int> want[N], cir[N];
int n, m, num, cnt;
int a[N], tmp[N], b[N];
int fa[N];
void dfs(int u) {
while(!want[u].empty()) {
int v = want[u].back();
want[u].pop_back();
dfs(a[v]);
cir[cnt].pb(v);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("2818.in", "r", stdin);
freopen("2818.out", "w", stdout);
#endif
int flag = 0, res = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i)
scanf("%d", &a[i]), tmp[i] = a[i];
sort(tmp + 1, tmp + n + 1);
num = unique(tmp + 1, tmp + n + 1) - (tmp + 1);
for(int i = 1; i <= n; ++ i)
b[i] = a[i] = lower_bound(tmp + 1, tmp + num + 1, a[i]) - tmp;
sort(b + 1, b + n + 1);
for(int i = 1; i <= n; ++ i)
if(a[i] != b[i])
want[b[i]].pb(i), -- m, flag = 1;
if(!flag) return printf("0"), 0;
if(m < 0) return printf("-1"), 0;
for(int i = 1; i <= num; ++ i)
if(!want[i].empty()) {
++ cnt; dfs(i);
}
if(cnt == 1) {
int sz = cir[1].size();
printf("1\n%d\n", sz);
for(int j = sz - 1; ~ j; -- j)
printf("%d ", cir[1][j]);
return 0;
}
if(m == 0) {
printf("%d", cnt);
for(int i = 1; i <= cnt; ++ i) {
int sz = cir[i].size();
printf("\n%d\n", sz);
for(int j = sz - 1; ~ j; -- j)
printf("%d ", cir[i][j]);
}
return 0;
}
m = min(m, cnt);
if(m > 1) printf("%d\n", cnt - m + 2);
else printf("%d\n", cnt);
for(int i = cnt; i > m; -- i) {
int sz = cir[i].size();
printf("%d\n", sz);
for(int j = sz - 1; ~ j; -- j)
printf("%d ", cir[i][j]);
puts("");
}
for(int i = 1; i <= m; ++ i)
res += cir[i].size();
printf("%d\n", res);
for(int i = 1; i <= m; ++ i)
for(int j = cir[i].size() - 1; ~ j; -- j)
printf("%d ", cir[i][j]);
if(m > 1) {
printf("\n%d\n", m);
for(int i = m; i > 0; -- i)
printf("%d ", cir[i][cir[i].size() - 1]);
}
return 0;
}