• [ICPC2020昆明J] Parallel Sort


    [ICPC2020昆明J] Parallel Sort - 构造

    Description

    给定一个 (n(n le 10^5)),然后长度为 (n) 的全排列 (a)。每次可以交换任意组(一组两个数,两两交换,不重复)的数。问最少交换多少轮能将整个排列排序。

    Solution

    排列/置换相关问题想象成 (i o 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;
        }
    }
    
  • 相关阅读:
    EUI库
    EUI库
    EUI库
    EUI库
    EUI库
    EUI库
    EUI库
    EUI库
    EUI库
    EUI库
  • 原文地址:https://www.cnblogs.com/mollnn/p/14622840.html
Copyright © 2020-2023  润新知