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

Solution 1 (runtime: 405 ms):
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
ll i,j,k,t,n,m;
struct pxy
{
	ll x,y;
};
int main()
{
	cin>>n;
	ll a[n+10],b[n+10];
	map<ll,ll>vv;
	for(i=1;i<=n;i++)cin>>a[i],b[i]=i,vv[b[i]]=i;
	pxy c[2000000];
	ll q=0;
	for(i=n;i>=1;i--)
	{
			for(j=vv[a[i]];j>1;j--)
			{
				c[++q].x=b[j],c[q].y=b[j-1];
				vv[b[j]]=j-1;
				vv[b[j-1]]=j;
				swap(b[j],b[j-1]);
			}
			for(j=1;j<i;j++)
			{
				c[++q].x=b[j+1],c[q].y=b[j];
				vv[b[j]]=j+1;
				vv[b[j+1]]=j;
				swap(b[j],b[j+1]);
			}
	}
	cout<<q<<'\n';
	for(i=1;i<=q;i++)
	{
		cout<<c[i].x<<' '<<c[i].y<<'\n';
	}
}

Solution 2 (runtime: 312 ms):
using namespace std;
#define ll long long int
#define ull unsigned long long int
#define pb push_back
#define ti tuple<int, int, int>
#define pii pair<int, int>
#define pli pair<ll, int>
#define pll pair<ll, ll>
#define mp make_pair
#define mt make_tuple
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <numeric>
#include <map>
#include <string>
#include <climits>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <set> 
#include <list>
#include <chrono>
#include <stack>
#ifndef DEBUG_TEMPLATE_CPP
#define DEBUG_TEMPLATE_CPP
// #define cerr cout
namespace __DEBUG_UTIL__
{
	using namespace std;
	template <typename T>
	concept is_iterable = requires(T && x) { begin(x); } &&
		!is_same_v<remove_cvref_t<T>, string>;
	void print(const char* x) { cerr << x; }
	void print(char x) { cerr << "\'" << x << "\'"; }
	void print(bool x) { cerr << (x ? "T" : "F"); }
	void print(string x) { cerr << "\"" << x << "\""; }
	void print(vector<bool>& v)
	{ /* Overloaded this because stl optimizes vector<bool> by using
		 _Bit_reference instead of bool to conserve space. */
		int f = 0;
		cerr << '{';
		for (auto&& i : v)
			cerr << (f++ ? "," : "") << (i ? "T" : "F");
		cerr << "}";
	}
	template <typename T>
	void print(T&& x)
	{
		if constexpr (is_iterable<T>)
			if (size(x) && is_iterable<decltype(*(begin(x)))>)
			{ /* Iterable inside Iterable */
				int f = 0;
				cerr << "\n~~~~~\n";
				for (auto&& i : x)
				{
					cerr << setw(2) << left << f++, print(i), cerr << "\n";
				}
				cerr << "~~~~~\n";
			}
			else
			{ /* Normal Iterable */
				int f = 0;
				cerr << "{";
				for (auto&& i : x)
					cerr << (f++ ? "," : ""), print(i);
				cerr << "}";
			}
		else if constexpr (requires { x.pop(); }) /* Stacks, Priority Queues, Queues */
		{
			auto temp = x;
			int f = 0;
			cerr << "{";
			if constexpr (requires { x.top(); })
				while (!temp.empty())
					cerr << (f++ ? "," : ""), print(temp.top()), temp.pop();
			else
				while (!temp.empty())
					cerr << (f++ ? "," : ""), print(temp.front()), temp.pop();
			cerr << "}";
		}
		else if constexpr (requires { x.first; x.second; }) /* Pair */
		{
			cerr << '(', print(x.first), cerr << ',', print(x.second), cerr << ')';
		}
		else if constexpr (requires { get<0>(x); }) /* Tuple */
		{
			int f = 0;
			cerr << '(', apply([&f](auto... args)
				{ ((cerr << (f++ ? "," : ""), print(args)), ...); },
				x);
			cerr << ')';
		}
		else
			cerr << x;
	}
	template <typename T, typename... V>
	void printer(const char* names, T&& head, V &&...tail)
	{
		int i = 0;
		for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++)
			if (names[i] == '(' or names[i] == '<' or names[i] == '{')
				bracket++;
			else if (names[i] == ')' or names[i] == '>' or names[i] == '}')
				bracket--;
		cerr.write(names, i) << " = ";
		print(head);
		if constexpr (sizeof...(tail))
			cerr << " ||", printer(names + i + 1, tail...);
		else
			cerr << "]\n";
	}
	template <typename T, typename... V>
	void printerArr(const char* names, T arr[], size_t N, V... tail)
	{
		size_t i = 0;
		for (; names[i] and names[i] != ','; i++)
			cerr << names[i];
		for (i++; names[i] and names[i] != ','; i++)
			;
		cerr << " = {";
		for (size_t ind = 0; ind < N; ind++)
			cerr << (ind ? "," : ""), print(arr[ind]);
		cerr << "}";
		if constexpr (sizeof...(tail))
			cerr << " ||", printerArr(names + i + 1, tail...);
		else
			cerr << "]\n";
	}

}
#ifndef ONLINE_JUDGE
#define debug(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__)
#define debugArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...)
#define debugArr(...)
#endif
#endif


vector<ll> subset;
string p;
vector<string> perms;
unordered_set<string> us;
void generate_subsets(vector<ll> v, ll cur, ll num) {
	if (cur == v.size()) {
		// process subset
		subset.push_back(num);
	}
	else {
		generate_subsets(v, cur + 1, num);
		num += v[cur];
		generate_subsets(v, cur + 1, num);
		num -= v[cur];
	}
}

vector<int> primes;
unordered_set<int> pri;
void SieveOfEratosthenes(int n)
{
	// Create a boolean array "prime[0..n]" and initialize
	// all entries it as true. A value in prime[i] will
	// finally be false if i is Not a prime, else true.
	bool prime[1000001];
	memset(prime, true, sizeof(prime));

	for (int p = 2; p * p <= n; p++) {
		// If prime[p] is not changed, then it is a prime
		if (prime[p] == true) {
			// Update all multiples of p greater than or
			// equal to the square of it numbers which are
			// multiple of p and are less than p^2 are
			// already been marked.
			for (int i = p * p; i <= n; i += p)
				prime[i] = false;
		}
	}

	// Print all prime numbers
	for (int p = 2; p <= n; p++)
		if (prime[p]) {
			primes.push_back(p);
			pri.insert(p);
		}
}

unordered_set<int> primeFactors(ll n)
{
	unordered_set<int> m2;

	int count = 0;
	while (n % 2 == 0)
	{
		n = n / 2;
		count++;
	}
	if (count > 0)
		m2.insert(2);

	for (ll i = 3; i <= sqrt(n); i = i + 2)
	{
		count = 0;
		while (n % i == 0)
		{
			n = n / i;
			count++;
		}
		if (count > 0)
			m2.insert(i);

	}

	// This condition is to handle the case when n
	// is a prime number greater than 2
	if (n > 2) {

		m2.insert(n);

	}
	return m2;
}


struct LRUCache {
public:
	size_t m_capacity;
	unordered_map<int, list<pair<int, int>>::iterator> m_map;
	list<pair<int, int>> m_list;
	LRUCache(size_t capacity) :m_capacity(capacity) {
	}
	int get(int key) {
		auto found_iter = m_map.find(key);
		if (found_iter == m_map.end()) //key doesn't exist
			return -1;
		m_list.splice(m_list.begin(), m_list, found_iter->second); //move the node corresponding to key to front
		return found_iter->second->second;
	}
	int set(int key, int value) {
		auto found_iter = m_map.find(key);
		if (found_iter != m_map.end()) //key exists
		{
			m_list.splice(m_list.begin(), m_list, found_iter->second);
			found_iter->second->second = value;
			return -1;
		}
		int key_to_del = -1;
		if (m_map.size() == m_capacity)
		{
			key_to_del = m_list.back().first;
			m_list.pop_back();
			m_map.erase(key_to_del);
		}
		m_list.emplace_front(key, value);
		m_map[key] = m_list.begin();
		return key_to_del;
	}
};

struct hashFunction
{
	size_t operator()(const pair<int,
		int>& x) const
	{
		return x.first ^ x.second;
	}
};

struct DSU {
	vector<int> e;
	DSU(int N) { e = vector<int>(N, -1); }

	// get representive component (uses path compression)
	int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }

	bool same_set(int a, int b) { return get(a) == get(b); }

	int size(int x) { return -e[get(x)]; }

	bool unite(int x, int y) {  // union by size
		x = get(x), y = get(y);
		if (x == y) return false;
		if (e[x] > e[y]) swap(x, y);
		e[x] += e[y]; e[y] = x;
		return true;
	}
};
class Compare {
public:
	bool operator()(pair<int, pair<int, int>> p1, pair<int, pair<int, int>> p2) {
		if (p1.first < p2.first) {
			return true;
		}
		else if (p1.first == p2.first
			&& p1.second.first > p2.second.first) {
			return true;
		}

		return false;
	}
};
set<int> commDiv(int a, int b)
{
	set<int> v;
	// find gcd of a, b
	int n = gcd(a, b);
	v.insert(n);
	// Count divisors of n.
	int result = 0;
	for (int i = 1; i <= sqrt(n); i++) {
		// if 'i' is factor of n
		if (n % i == 0) {
			v.insert(i);
		}
	}
	return v;
}

class SegmentTree {
private:
	std::vector<int> tree;
	int n;

	void buildTree(const std::vector<ll>& arr, int treeIndex, int lo, int hi) {
		if (lo == hi) {
			tree[treeIndex] = arr[lo];
			return;
		}

		int mid = lo + (hi - lo) / 2;
		buildTree(arr, 2 * treeIndex + 1, lo, mid);
		buildTree(arr, 2 * treeIndex + 2, mid + 1, hi);

		tree[treeIndex] = std::max(tree[2 * treeIndex + 1], tree[2 * treeIndex + 2]);
	}

	ll queryMax(int treeIndex, int lo, int hi, int i, int j) {
		if (lo > j || hi < i) return std::numeric_limits<int>::min(); // Out of range
		if (i <= lo && j >= hi) return tree[treeIndex]; // Completely within range

		int mid = lo + (hi - lo) / 2;
		return std::max(queryMax(2 * treeIndex + 1, lo, mid, i, j),
			queryMax(2 * treeIndex + 2, mid + 1, hi, i, j));
	}

public:
	SegmentTree(const std::vector<ll>& arr) {
		n = arr.size();
		tree.assign(4 * n, 0); // Allocate memory
		buildTree(arr, 0, 0, n - 1);
	}

	int queryMax(int i, int j) {
		return queryMax(0, 0, n - 1, i, j);
	}
};

vector<int> z_function(string& s) {
	int n = s.size();
	vector<int> z(n);
	int l = 0, r = 0;
	for (int i = 1; i < n; i++) {
		if (i < r) {
			z[i] = min(r - i, z[i - l]);
		}
		while (i + z[i] < n && s[z[i]] == s[i + z[i]]) {
			z[i]++;
		}
		if (i + z[i] > r) {
			l = i;
			r = i + z[i];
		}
	}
	return z;
}

vector<int> findDivisors(int n) {
	vector<int> divisors;
	for (int i = 1; i <= sqrt(n); ++i) {
		if (n % i == 0) {
			divisors.push_back(i);          // Add the smaller divisor
			if (i != n / i) {
				divisors.push_back(n / i);  // Add the larger divisor if distinct
			}
		}
	}
	sort(divisors.begin(), divisors.end()); // Optional: Sort divisors
	return divisors;
}

long long modPow(long long a, long long b, long long m) {
	long long result = 1;
	a = a % m;
	while (b > 0) {
		if (b % 2 == 1) {
			result = (result * a) % m;
		}
		b = b >> 1; // Divide b by 2
		a = (a * a) % m;
	}
	return result;
}

// Calculates the modular inverse of a mod m, assuming m is prime
long long modInverse(long long a, long long m) {
	return modPow(a, m - 2, m); // Fermat's Little Theorem
}
struct CustomHash {
	static uint64_t splitmix64(uint64_t x) {
		x += 0x9e3779b97f4a7c15;
		x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
		x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
		return x ^ (x >> 31);
	}
	size_t operator()(uint64_t x) const {
		static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
		return splitmix64(x + FIXED_RANDOM);
	}
};
class FenwickTree {
	vector<int> tree;
	int size;

public:
	FenwickTree(int n) : size(n) {
		tree.resize(n + 1, 0);
	}

	// Update the frequency of a number (increment by 1)
	void update(int idx, int delta) {
		while (idx <= size) {
			tree[idx] += delta;
			idx += idx & -idx; // Move to the next index
		}
	}

	// Query the cumulative frequency up to idx
	int query(int idx) {
		int sum = 0;
		while (idx > 0) {
			sum += tree[idx];
			idx -= idx & -idx; // Move to the parent index
		}
		return sum;
	}
};
bool f = false;
bool can(int rem, int rem2, string& s, int i, int curp, int k, int taken) {
	if (f) 
		return true;
	if (rem == 0 && rem2 == 0 && curp % k == 0) {
		f = true;
		return true;
	}
	else if ((rem == 0 && rem2 == 0) || i >= s.size()) return false;
	bool f2 = false;
	if (s[i] == '1' && rem2 > 0) {
		f2 = can(rem, rem2 - 1, s, i + 1, curp, k, taken + 1);
	}
	else if (s[i] == '0' && rem > 0) {
		f2 = can(rem - 1, rem2, s, i + 1, curp + taken, k, taken);
	}

	return can(rem, rem2, s, i + 1, curp, k, taken) || f2;
}
int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	
		int n;
		cin >> n;
		vector<int> v2,v;
		map<int, int> m,m2;
		int cur = 1;
		for (int i = 0; i < n; i++) {
			int num;
			cin >> num;
			v.push_back(num);
			v2.push_back(cur);
			m2[cur] = i;
			m[num] = i;
			cur++;
		}
		vector<pii> ans;
		map<int, set<int>> swaps;
		for (int i = 0; i < n; i++) {
			int curn = v[i];
			int curp = m2[curn];
			if (v2[i] == curn) {
				int curi = i;
				while (i + 1 < n && m[v[i + 1]] >= curi) {
					ans.push_back({ v[i+1],v[i]});
					swaps[v[i]].insert(v[i + 1]);
					swaps[v[i+1]].insert(v[i]);
					swap(v[i + 1], v[i]);
					i++;
				}
				while (i > curi) {
					ans.push_back({ v[i],v[i-1] });
					swap(v[i], v[i-1]);
					i--;
				}
				i = curi;
			}
			while (v2[i] != curn) {
				ans.push_back({ v2[curp],v2[curp - 1] });
				swap(v2[curp], v2[curp - 1]);
				m2[v2[curp]] = curp;
				m2[v2[curp-1]] = curp-1;
				curp--;
			}
		}
		for (int i = 0; i < n-1; i++) {
			if (v[i + 1] > v[i]&&!swaps[v[i]].contains(v[i+1])) {
				ans.pb({ v[i + 1],v[i] });
				ans.pb({ v[i],v[i + 1] });
			}
		}
		cout << ans.size() << '\n';
		for (int i = 0; i < ans.size(); i++) {
			
			cout << ans[i].first << ' ' << ans[i].second << '\n';
		}
}