Codeforces Global Round 3 C. Crazy Diamond

Crazy Diamond

time limit per test: 3 second memory limit per test: 256 megabytes input: standard input output: standard output

You are given a permutation p p p of integers from 1 1 1 to n n n, where n n n is an even number.

Your goal is to sort the permutation. To do so, you can perform zero or more operations of the following type:

  • take two indices i i i and j j j such that 2 ⋅ ∣ i − j ∣ ≥ n 2 \cdot |i - j| \geq n 2⋅∣i−j∣≥n and swap p i p_i pi and p j p_j pj.

There is no need to minimize the number of operations, however you should use no more than 5 ⋅ n 5 \cdot n 5⋅n operations. One can show that it is always possible to do that.

Input

The first line contains a single integer n n n ( 2 ≤ n ≤ 3 ⋅ 1 0 5 2 \leq n \leq 3 \cdot 10^5 2≤n≤3⋅105, n n n is even) --- the length of the permutation.

The second line contains n n n distinct integers p 1 , p 2 , ... , p n p_1, p_2, \ldots, p_n p1,p2,...,pn ( 1 ≤ p i ≤ n 1 \le p_i \le n 1≤pi≤n) --- the given permutation.

Output

On the first line print m m m ( 0 ≤ m ≤ 5 ⋅ n 0 \le m \le 5 \cdot n 0≤m≤5⋅n) --- the number of swaps to perform.

Each of the following m m m lines should contain integers a i , b i a_i, b_i ai,bi ( 1 ≤ a i , b i ≤ n 1 \le a_i, b_i \le n 1≤ai,bi≤n, ∣ a i − b i ∣ ≥ n 2 |a_i - b_i| \ge \frac{n}{2} ∣ai−bi∣≥2n) --- the indices that should be swapped in the corresponding swap.

Note that there is no need to minimize the number of operations. We can show that an answer always exists.

Example

i n p u t \tt input input
2 2 1
o u t p u t \tt output output
1 1 2
i n p u t \tt input input
4 3 4 1 2
o u t p u t \tt output output
4 1 4 1 4 1 3 2 4
i n p u t \tt input input
6 2 5 3 1 4 6
o u t p u t \tt output output
3 1 5 2 5 1 4

Note

In the first example, when one swap elements on positions 1 1 1 and 2 2 2, the array becomes sorted.

In the second example, pay attention that there is no need to minimize number of swaps.

In the third example, after swapping elements on positions 1 1 1 and 5 5 5 the array becomes: [ 4 , 5 , 3 , 1 , 2 , 6 ] [4, 5, 3, 1, 2, 6] [4,5,3,1,2,6]. After swapping elements on positions 2 2 2 and 5 5 5 the array becomes [ 4 , 2 , 3 , 1 , 5 , 6 ] [4, 2, 3, 1, 5, 6] [4,2,3,1,5,6] and finally after swapping elements on positions 1 1 1 and 4 4 4 the array becomes sorted: [ 1 , 2 , 3 , 4 , 5 , 6 ] [1, 2, 3, 4, 5, 6] [1,2,3,4,5,6].

Tutorial

由题意得,设当前位置坐标为 i i i,数字 i i i 所在位置为 j j j,此时会出现以下三种情况:

  • 如果 ∣ i − j ∣ ≥ n 2 |i - j| \ge {n \over 2} ∣i−j∣≥2n,则只需要交换 i i i 位置和 j j j 位置的元素即可
  • 如果 ∣ i − j ∣ < n 2 ∪ i > n 2 |i - j| < {n \over 2} \cup i > {n \over 2} ∣i−j∣<2n∪i>2n,此时可以让 1 1 1 位置承担了中间转运的作用,可以将 1 1 1 位置上的元素和 i i i 位置上的元素交换,然后将 1 1 1 位置上的元素和 j j j 位置元素上的位置交换,最后将 1 1 1 位置上的元素和 i i i 位置上的元素再交换一次即可
  • 如果 ∣ i − j ∣ < n 2 ∪ j ≤ n 2 |i - j| < {n \over 2} \cup j \le {n \over 2} ∣i−j∣<2n∪j≤2n,此时可以让 n n n 位置承担了中间转运的作用,可以将 n n n 位置上的元素和 i i i 位置上的元素交换,然后将 n n n 位置上的元素和 j j j 位置元素上的位置交换,最后将 n n n 位置上的元素和 i i i 位置上的元素再交换一次即可
  • 如果 ∣ i − j ∣ < n 2 ∪ i ≤ n 2 ∪ j ≥ n 2 |i - j| < {n \over 2} \cup i \le {n \over 2} \cup j \ge {n \over 2} ∣i−j∣<2n∪i≤2n∪j≥2n,此时可以让 1 1 1 位置和 n n n 位置承担了中间转运的作用,可以先将 i i i 位置上的元素和 n n n 位置上的元素交换,然后将 1 1 1 位置上的元素和 n n n 位置元素上的位置交换,然后将 1 1 1 位置上的元素和 j j j 位置元素上的位置交换,然后将 1 1 1 位置上的元素和 n n n 位置元素上的位置交换,最后将 i i i 位置上的元素和 n n n 位置上的元素再交换一次即可

举几个例子不难得出,起到中间转运作用的 1 1 1 位置和 n n n 位置上的元素均未发生变化,而 i i i 位置和 j j j 位置上的元素调换了位置,题目中提到操作次数不超过 5 ⋅ n 5 \cdot n 5⋅n 次,此方法最多操作 5 ⋅ n 2 + 3 ⋅ n 2 = 4 n 5 \cdot \frac{n}{2} + 3 \cdot \frac{n}{2} = 4 n 5⋅2n+3⋅2n=4n 次(因为当 i ≥ n 2 + 1 i \ge {n \over 2} + 1 i≥2n+1 时必定只需要三次交换,所以第四种情况最多发生 n 2 n \over 2 2n 次)

此解法时间复杂度为 O ( n ) \mathcal O(n) O(n)

Solution

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define PII pair<int, int>

signed main() {
    int n;
    cin >> n;
    vector<int> p(n + 1), idx(n + 1);
    vector<PII> ans;
    for (int i = 1; i <= n; ++i) {
        cin >> p[i];
        idx[p[i]] = i;
    }
    
    function<void(int, int)> SWAP = [&](int x, int y) {
        ans.emplace_back(x, y);
        swap(idx[p[x]], idx[p[y]]);
        swap(p[x], p[y]);
    };
    
    for (int i = 1; i <= n; ++i) {
        if (p[i] != i) {
            int j = idx[i];
            if (abs(j - i) >= n / 2) {
                SWAP(i, j);
            } else {
                if (i > n / 2) {
                    SWAP(1, i); SWAP(1, j); SWAP(1, i);
                } else if (n - j >= n / 2) {
                    SWAP(i, n); SWAP(j, n); SWAP(i, n);
                } else {
                    SWAP(i, n); SWAP(1, n); SWAP(1, j); SWAP(1, n); SWAP(i, n);
                }
            }
        }
    }
    cout << ans.size() << endl;
    for (auto [x, y] : ans) {
        cout << x << " " << y << endl;
    }
    return 0;
}
相关推荐
老赵聊算法、大模型备案3 小时前
北京市生成式人工智能服务已备案信息公告(2025年12月11日)
人工智能·算法·安全·aigc
CoderYanger4 小时前
C.滑动窗口-求子数组个数-越长越合法——2799. 统计完全子数组的数目
java·c语言·开发语言·数据结构·算法·leetcode·职场和发展
厕所博士4 小时前
红黑树原理前置理解—— 2-3 树
算法·2-3树·红黑树原理理解前置
萌>__<新5 小时前
力扣打卡每日一题————除自身外所有元素的乘积
数据结构·算法
xu_yule5 小时前
算法基础—搜索(2)【记忆化搜索+BFS+01BFS+Floodfill]
数据结构·算法
LinHenrY12275 小时前
初识C语言(自定义结构:结构体)
c语言·开发语言
s09071365 小时前
Xilinx FPGA使用 FIR IP 核做匹配滤波时如何减少DSP使用量
算法·fpga开发·xilinx·ip core·fir滤波
老马啸西风5 小时前
成熟企业级技术平台-10-跳板机 / 堡垒机(Bastion Host)详解
人工智能·深度学习·算法·职场和发展
子夜江寒5 小时前
逻辑回归简介
算法·机器学习·逻辑回归
软件算法开发6 小时前
基于ACO蚁群优化算法的多车辆含时间窗VRPTW问题求解matlab仿真
算法·matlab·aco·vrptw·蚁群优化·多车辆·时间窗