#include <algorithm>
#include <iostream>
#include <vector>
#include "message.h"
#include "teatr.h"
int first_of(int index, int n) {
return std::min(index, 14) * n / 14;
}
template<class RandomIt1, class RandomIt2>
long long count_inversions(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, RandomIt2 last2) {
long long result = 0;
while (first1 != last1 && first2 != last2) {
if (*first2 < *first1) {
result += last1 - first1;
++first2;
} else {
++first1;
}
}
return result;
}
template<class RandomIt>
long long merge_sort(RandomIt first, RandomIt last) {
long long result = 0;
int size = last - first;
if (size == 2) {
RandomIt second = first;
++second;
result = *second < *first;
if (result)
std::iter_swap(first, second);
} else if (size > 2) {
RandomIt mid = first + size / 2;
result += merge_sort(first, mid);
result += merge_sort(mid, last);
result += count_inversions(first, mid, mid, last);
std::inplace_merge(first, mid, last);
}
return result;
}
int main() {
int id = MyNodeId();
long long result = 0;
if (id == 0) {
for (int i = 1; i < 100; i++) {
int source = Receive(-1);
result += GetLL(source);
}
std::cout << result;
} else {
int left_index = -id;
int right_index = 0;
while (left_index < 0) {
right_index++;
left_index += right_index;
}
int n = GetN();
int left_first = first_of(left_index, n);
int left_last = first_of(left_index + 1, n);
int right_first = first_of(right_index, n);
int right_last = first_of(right_index + 1, n);
std::vector<int> left_array(left_last - left_first);
std::vector<int> right_array(right_last - right_first);
int i = left_first;
for (auto&& e : left_array) {
e = GetElement(i++);
}
i = right_first;
for (auto&& e : right_array) {
e = GetElement(i++);
}
if (right_index == left_index + 1)
result = merge_sort(left_array.begin(), left_array.end());
else
std::sort(left_array.begin(), left_array.end());
std::sort(right_array.begin(), right_array.end());
result += count_inversions(left_array.begin(), left_array.end(), right_array.begin(), right_array.end());
PutLL(0, result);
Send(0);
}
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 | #include <algorithm> #include <iostream> #include <vector> #include "message.h" #include "teatr.h" int first_of(int index, int n) { return std::min(index, 14) * n / 14; } template<class RandomIt1, class RandomIt2> long long count_inversions(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, RandomIt2 last2) { long long result = 0; while (first1 != last1 && first2 != last2) { if (*first2 < *first1) { result += last1 - first1; ++first2; } else { ++first1; } } return result; } template<class RandomIt> long long merge_sort(RandomIt first, RandomIt last) { long long result = 0; int size = last - first; if (size == 2) { RandomIt second = first; ++second; result = *second < *first; if (result) std::iter_swap(first, second); } else if (size > 2) { RandomIt mid = first + size / 2; result += merge_sort(first, mid); result += merge_sort(mid, last); result += count_inversions(first, mid, mid, last); std::inplace_merge(first, mid, last); } return result; } int main() { int id = MyNodeId(); long long result = 0; if (id == 0) { for (int i = 1; i < 100; i++) { int source = Receive(-1); result += GetLL(source); } std::cout << result; } else { int left_index = -id; int right_index = 0; while (left_index < 0) { right_index++; left_index += right_index; } int n = GetN(); int left_first = first_of(left_index, n); int left_last = first_of(left_index + 1, n); int right_first = first_of(right_index, n); int right_last = first_of(right_index + 1, n); std::vector<int> left_array(left_last - left_first); std::vector<int> right_array(right_last - right_first); int i = left_first; for (auto&& e : left_array) { e = GetElement(i++); } i = right_first; for (auto&& e : right_array) { e = GetElement(i++); } if (right_index == left_index + 1) result = merge_sort(left_array.begin(), left_array.end()); else std::sort(left_array.begin(), left_array.end()); std::sort(right_array.begin(), right_array.end()); result += count_inversions(left_array.begin(), left_array.end(), right_array.begin(), right_array.end()); PutLL(0, result); Send(0); } return 0; } |
English