icpc昆明 Parallel Sort

传送门

不端进行两两交换,使得用最小的轮数使得最后的数组是一个序列

其实轮数是很少的,就可以进行模拟。

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define CASE int Kase = 0; cin >> Kase; for(int kase = 1; kase <= Kase; kase++)
using namespace std;
template<typename T = long long> inline T read() {
    T s = 0, f = 1; char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    while(isdigit(ch)) {s = (s << 3) + (s << 1) + ch - 48; ch = getchar();}
    return s * f;
}
#ifdef ONLINE_JUDGE
#define qaq(...) ;
#define qwq(c) ;
#else
#define qwq(a, b) for_each(a, b, [=](int x){cerr << x << " ";}), cerr << std::endl
template <typename... T> void qaq(const T &...args) {
    auto &os = std::cerr;
    (void)(int[]){(os << args << " ", 0)...};
    os << std::endl;
}
#endif
const int N = 2e5 + 5, M = 1e6 + 5, MOD = 1e9 + 7, CM = 998244353, INF = 0x3f3f3f3f; const ll linf = 0x7f7f7f7f7f7f7f7f;
int a[N], vis[N];
bool check(int n){
    for(int i = 1; i <= n; i++)
        if(i != a[i]) return true;
    return false;
}
void solve(int kase){
    int n = read();
    for(int i = 1; i <= n; i++) a[i] = read(), vis[i] = 0;
    int tot = 0;
    for(int i = 1; i <= n; i++) {
        if(a[i] == i) tot++;
    }
    vector<vector<int>> v;
    while(check(n)){
        v.push_back(vector<int>());
        for(int i = 1; i <= n; i++) vis[i] = 0;
        for(int i = 1; i <= n; i++){
            if(vis[i]) continue;
            int x = a[i];
            if(a[i] == i) continue;
            vector<int> now(1, 0);
            int nowtot = 1;
            now.push_back(i);
            while(x != i) vis[x] = 1, now.push_back(x), x = a[x], nowtot++;
            for(int j = 1; j <= nowtot / 2; j++) {
                v.back().push_back(now[j]);
                v.back().push_back(now[nowtot - j + 1]);
                swap(a[now[j]], a[now[nowtot - j + 1]]);
            }
        }
    }
    printf("%lu\n", v.size());
    for(int i = 0; i < v.size(); i++) {
        printf("%lu ", v[i].size() / 2);
        for(int j = 0; j < v[i].size(); j++) {
            printf("%d%c", v[i][j], " \n"[j == v[i].size() - 1]);
        }
    }
}
const bool ISFILE = 0, DUO = 0;
int main(){
    clock_t start, finish; start = clock();
    if(ISFILE) freopen("/Users/i/Desktop/practice/in.txt", "r", stdin);
    if(DUO) {CASE solve(kase);} else solve(1);
    finish = clock();
    qaq("\nTime:", (double)(finish - start) / CLOCKS_PER_SEC * 1000, "ms\n");
    return 0;
}
posted @ 2021-05-08 20:45  Emcikem  阅读(108)  评论(0编辑  收藏  举报