#include <iostream> #include <vector> #include <algorithm> #include <list> #include <utility> using namespace std; void createCycle( int index, const vector<int> &items, const vector<int> &sorted, vector<bool> &visited, list<list<int> > &cycles) { visited[index] = true; if (items[index] == sorted[index]) return; cycles.emplace_back(); cycles.back().push_back(index); while (true) { int destination = distance(sorted.begin(), lower_bound(sorted.begin(), sorted.end(), items[index])); if (cycles.back().front() == destination) break; cycles.back().push_back(destination); index = destination; visited[destination] = true; } } int getRoundsFromCycleSize(int cycleSize) { int result = 0; while (cycleSize > 1) { cycleSize = cycleSize / 2 + (cycleSize % 2 == 1); result++; } return result; } int calculateRounds(const list<list<int> > &cycles) { int cycleSize = 0; for (auto &cycle: cycles) { cycleSize = max(cycleSize, (int) cycle.size()); } return getRoundsFromCycleSize(cycleSize); } int executeRound(list<int> &cycle, vector<pair<int, int> > &pairsContainer) { int pairs = 0; auto it = cycle.begin(); while (it != cycle.end()) { auto nextIt = next(it, 1); if (nextIt == cycle.end()) { break; } pairsContainer.emplace_back(*it, *nextIt); pairs++; it = cycle.erase(nextIt); advance(it, 1); } return pairs; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int n; cin >> n; vector<int> items, sorted; items.reserve(n); for (int i = 0; i < n; i++) { int v; cin >> v; items.push_back(v); } sorted.resize(n); copy(items.begin(), items.end(), sorted.begin()); sort(sorted.begin(), sorted.end()); vector<bool> visited(n, false); list<list<int> > cycles; for (int i = 0; i < n; i++) { if (visited[i]) { continue; } createCycle(i, items, sorted, visited, cycles); } int rounds = calculateRounds(cycles); cout << rounds << endl; while (!cycles.empty()) { vector<pair<int, int> > pairsToSwap; for (auto it = cycles.begin(); it != cycles.end();) { int count = executeRound(*it, pairsToSwap); if (count == 0) it = cycles.erase(it); else ++it; } if (pairsToSwap.empty()) break; cout << pairsToSwap.size() * 2 << endl; for (auto &pair: pairsToSwap) { cout << pair.first + 1 << " "; } for (auto rit = pairsToSwap.rbegin(); rit != pairsToSwap.rend(); ++rit) { cout << rit->second + 1 << " "; } cout << endl; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include <iostream> #include <vector> #include <algorithm> #include <list> #include <utility> using namespace std; void createCycle( int index, const vector<int> &items, const vector<int> &sorted, vector<bool> &visited, list<list<int> > &cycles) { visited[index] = true; if (items[index] == sorted[index]) return; cycles.emplace_back(); cycles.back().push_back(index); while (true) { int destination = distance(sorted.begin(), lower_bound(sorted.begin(), sorted.end(), items[index])); if (cycles.back().front() == destination) break; cycles.back().push_back(destination); index = destination; visited[destination] = true; } } int getRoundsFromCycleSize(int cycleSize) { int result = 0; while (cycleSize > 1) { cycleSize = cycleSize / 2 + (cycleSize % 2 == 1); result++; } return result; } int calculateRounds(const list<list<int> > &cycles) { int cycleSize = 0; for (auto &cycle: cycles) { cycleSize = max(cycleSize, (int) cycle.size()); } return getRoundsFromCycleSize(cycleSize); } int executeRound(list<int> &cycle, vector<pair<int, int> > &pairsContainer) { int pairs = 0; auto it = cycle.begin(); while (it != cycle.end()) { auto nextIt = next(it, 1); if (nextIt == cycle.end()) { break; } pairsContainer.emplace_back(*it, *nextIt); pairs++; it = cycle.erase(nextIt); advance(it, 1); } return pairs; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int n; cin >> n; vector<int> items, sorted; items.reserve(n); for (int i = 0; i < n; i++) { int v; cin >> v; items.push_back(v); } sorted.resize(n); copy(items.begin(), items.end(), sorted.begin()); sort(sorted.begin(), sorted.end()); vector<bool> visited(n, false); list<list<int> > cycles; for (int i = 0; i < n; i++) { if (visited[i]) { continue; } createCycle(i, items, sorted, visited, cycles); } int rounds = calculateRounds(cycles); cout << rounds << endl; while (!cycles.empty()) { vector<pair<int, int> > pairsToSwap; for (auto it = cycles.begin(); it != cycles.end();) { int count = executeRound(*it, pairsToSwap); if (count == 0) it = cycles.erase(it); else ++it; } if (pairsToSwap.empty()) break; cout << pairsToSwap.size() * 2 << endl; for (auto &pair: pairsToSwap) { cout << pair.first + 1 << " "; } for (auto rit = pairsToSwap.rbegin(); rit != pairsToSwap.rend(); ++rit) { cout << rit->second + 1 << " "; } cout << endl; } return 0; } |