#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; } |
English