Problem: 2052A - Adrenaline Rush
Language: c++17 

Solution 1 (runtime: 234 ms):
#include <bits/stdc++.h>
using namespace std;
 
#ifdef LOCAL
#include "debug.h"
#else
#define dbg(...)
#endif


#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

//find_by_order(k): It returns to an iterator to the kth element (counting from zero)
//order_of_key(k): order_of_key(k) : It returns to the number of items that are strictly smaller than our item k
template<typename T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

// https://codeforces.com/problemset/problem/2052/A
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> c(n+1), idx(n+1), at(n+1), limit(n+1, n+1);
    ordered_set<int> os;
    for (int i = 1; i <= n; i++){
        cin >> c[i];
        at[c[i]] = i;
    }
    iota(idx.begin(), idx.end(), 0);
    set<pair<int,int>> seen;
    vector<pair<int,int>> ans;
    for (int i = n; i >= 1;i--){
        int curr = c[i] - os.order_of_key(c[i]);
        assert(curr <= at[c[i]] && idx[curr] == c[i]);
        
        //move all the way up
        for (int j = curr; j - 1 >= 1; j--){
            ans.push_back({idx[j], idx[j-1]});
            swap(idx[j], idx[j-1]);
        }
        int it = at[c[i]] - 1;
        curr = 1;
        //move to correct position
        while(it--){
            limit[idx[curr+1]] = min(limit[idx[curr+1]], at[c[i]]);
            ans.push_back({idx[curr+1], idx[curr]});
            swap(idx[curr], idx[curr+1]);
            curr++;
        }
        //at correct position
        assert(curr == at[c[i]]);
        //swap with values that we haven't swapped with before
        for (int j = curr; j + 1 <= limit[c[i]]-1; j++){
            ans.push_back({idx[j+1], idx[j]});
            swap(idx[j+1], idx[j]);
        }
        for (int j = limit[c[i]]-1; j-1 >= curr; j--){
            ans.push_back({idx[j], idx[j-1]});
            swap(idx[j], idx[j-1]);
        }
        os.insert(c[i]);
    }
    cout << ans.size() << '\n';
    for (auto &[x,y] : ans){
        cout << x << " " << y << '\n';
    }
    return 0;
}


Solution 2 (runtime: 233 ms):
#include <bits/stdc++.h>

#define ll long long


void solve () {
    int n; std::cin >> n;
    std::vector<int> v (n);
    for (int &i: v) {
        std::cin >> i;
    }
    
    std::vector<std::pair<int, int>> ans;
    // n, n - 1, ..., 1 first
    for (int i = 0; i < n; ++ i) {
        for (int j = 0; j < n - 1; ++ j) {
            if (v[j] < v[j + 1]) {
                std::swap(v[j], v[j + 1]);
                ans.push_back({ v[j], v[j + 1] });
            }
        }
    }
    
    // 1, 2, ..., n second
    for (int i = 0; i < n; ++ i) {
        for (int j = 0; j < n - 1; ++ j) {
            if (v[j] > v[j + 1]) {
                std::swap(v[j], v[j + 1]);
                ans.push_back({ v[j], v[j + 1] });
            }
        }
    }
    
    std::reverse(ans.begin(), ans.end());
    
    std::cout << ans.size() << '\n';
    for (std::pair<int, int> it: ans) {
        std::cout << it.second << ' ' << it.first << '\n';
    }
}

int32_t main () {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);
    std::cout.tie(NULL);
    int t = 1;
    // std::cin >> t;
    while (t --) {
        solve();
    }
    return 0;
}