#include <iostream> #include <vector> #include "message.h" #include "teatr.h" using namespace std; long long inversions = 0; vector<int> arr; void realMerge(vector<int> &toMerge, int lStart, int lEnd, int rEnd) { int leftPos = lStart, rightPos = lEnd + 1; vector<int> merged; while (leftPos <= lEnd || rightPos <= rEnd) { if (leftPos <= lEnd) { if (rightPos <= rEnd) { if (toMerge[leftPos] <= toMerge[rightPos]) { merged.push_back(toMerge[leftPos]); leftPos++; } else { inversions += lEnd - leftPos + 1; merged.push_back(toMerge[rightPos]); rightPos++; } } else { merged.push_back(toMerge[leftPos]); leftPos++; } } else { merged.push_back(toMerge[rightPos]); rightPos++; } } for (unsigned int i = 0; i < merged.size(); i++) { toMerge[lStart + i] = merged[i]; } } void merge(vector<int> &toSort, unsigned int start, unsigned int end) { if (start == end) { return; } unsigned int leftPos = start, rightPos = start + (end - start) / 2 + 1; merge(toSort, start, rightPos - 1); merge(toSort, rightPos, end); realMerge(toSort, leftPos, rightPos - 1, end); } void mergeSort(vector<int> &toSort) { merge(toSort, 0, (unsigned int)toSort.size() - 1); } void sendInfo(int target) { PutLL(target, inversions); PutInt(target, (int)arr.size()); for (auto elem : arr) { PutInt(target, elem); } Send(target); } void getInfo(int source) { Receive(source); inversions += GetLL(source); int size = GetInt(source); for (int i = 0; i < size; i++) { arr.push_back(GetInt(source)); } realMerge(arr, 0, (int)arr.size() - size - 1, (int)arr.size() - 1); } int main() { ios_base::sync_with_stdio(0); int id = MyNodeId(); int start = id * 1000000, end = start + 1000000 - 1; if (start > GetN() - 1) { return 0; } for (int i = start; i <= min(GetN() - 1, end); i++) { arr.push_back(GetElement(i)); } mergeSort(arr); // communication int whoSend = 2, level = 1; while (true) { if (arr.size() == GetN() && id == 0) { break; } if ((id - level) % whoSend == 0) { // has to send sendInfo(id - level); break; } else { if (start + arr.size() != GetN()) { // get info only if missing getInfo(id + level); } } whoSend *= 2; level *= 2; } if (id == 0) { cout << inversions << "\n"; } 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 119 120 121 122 123 124 125 126 127 | #include <iostream> #include <vector> #include "message.h" #include "teatr.h" using namespace std; long long inversions = 0; vector<int> arr; void realMerge(vector<int> &toMerge, int lStart, int lEnd, int rEnd) { int leftPos = lStart, rightPos = lEnd + 1; vector<int> merged; while (leftPos <= lEnd || rightPos <= rEnd) { if (leftPos <= lEnd) { if (rightPos <= rEnd) { if (toMerge[leftPos] <= toMerge[rightPos]) { merged.push_back(toMerge[leftPos]); leftPos++; } else { inversions += lEnd - leftPos + 1; merged.push_back(toMerge[rightPos]); rightPos++; } } else { merged.push_back(toMerge[leftPos]); leftPos++; } } else { merged.push_back(toMerge[rightPos]); rightPos++; } } for (unsigned int i = 0; i < merged.size(); i++) { toMerge[lStart + i] = merged[i]; } } void merge(vector<int> &toSort, unsigned int start, unsigned int end) { if (start == end) { return; } unsigned int leftPos = start, rightPos = start + (end - start) / 2 + 1; merge(toSort, start, rightPos - 1); merge(toSort, rightPos, end); realMerge(toSort, leftPos, rightPos - 1, end); } void mergeSort(vector<int> &toSort) { merge(toSort, 0, (unsigned int)toSort.size() - 1); } void sendInfo(int target) { PutLL(target, inversions); PutInt(target, (int)arr.size()); for (auto elem : arr) { PutInt(target, elem); } Send(target); } void getInfo(int source) { Receive(source); inversions += GetLL(source); int size = GetInt(source); for (int i = 0; i < size; i++) { arr.push_back(GetInt(source)); } realMerge(arr, 0, (int)arr.size() - size - 1, (int)arr.size() - 1); } int main() { ios_base::sync_with_stdio(0); int id = MyNodeId(); int start = id * 1000000, end = start + 1000000 - 1; if (start > GetN() - 1) { return 0; } for (int i = start; i <= min(GetN() - 1, end); i++) { arr.push_back(GetElement(i)); } mergeSort(arr); // communication int whoSend = 2, level = 1; while (true) { if (arr.size() == GetN() && id == 0) { break; } if ((id - level) % whoSend == 0) { // has to send sendInfo(id - level); break; } else { if (start + arr.size() != GetN()) { // get info only if missing getInfo(id + level); } } whoSend *= 2; level *= 2; } if (id == 0) { cout << inversions << "\n"; } return 0; } |