#include <cstdio> #include <cstdlib> #include <vector> // #include <iostream> #include "message.h" #include "teatr.h" #define LSOne(i) (i & (-i)) typedef unsigned long long ULL; constexpr unsigned MAX_ELEM = 1e6; unsigned counting_sort[MAX_ELEM + 1] = {0}; class FenwickTree { private: std::vector<unsigned> ft; public: FenwickTree(int n) { ft.assign(n + 1, 0); } int rsq(int b) { int sum = 0; for (; b; b -= LSOne(b)) sum += ft[b]; return sum; } // note: LSOne(S) (S & (-S)) int rsq(int a, int b) { return rsq(b) - (a == 1 ? 0 : rsq(a - 1)); } // returns RSQ(a, b) // adjusts value of the k-th element by v (v can be +ve/inc or -ve/dec) void adjust(int k, int v) { // note: n = ft.size() - 1 for (; k < (int)ft.size(); k += LSOne(k)) ft[k] += v; } }; int main() { const unsigned N = GetN(); const unsigned node_id = MyNodeId(); const unsigned range_start = (N / NumberOfNodes()) * (node_id); unsigned range_end = (N / NumberOfNodes()) * (node_id + 1); if (node_id == NumberOfNodes() - 1) range_end = N; for (unsigned i = 0; i < range_start; ++i) ++counting_sort[ GetElement(i) ]; FenwickTree ftree(MAX_ELEM); for (unsigned i = 1; i <= MAX_ELEM; ++i) ftree.adjust(i, counting_sort[i]); ULL inversion_count = 0ULL; for (unsigned i = range_start; i < range_end; ++i) { inversion_count += ftree.rsq( GetElement(i) + 1, MAX_ELEM ); ftree.adjust(GetElement(i), 1); } if (node_id != 0) { PutLL(0, inversion_count); Send(0); } if (node_id == 0) { for (int i = 1; i < NumberOfNodes(); ++i) { Receive(i); inversion_count += GetLL(i); } printf("%llu\n", inversion_count); } 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 | #include <cstdio> #include <cstdlib> #include <vector> // #include <iostream> #include "message.h" #include "teatr.h" #define LSOne(i) (i & (-i)) typedef unsigned long long ULL; constexpr unsigned MAX_ELEM = 1e6; unsigned counting_sort[MAX_ELEM + 1] = {0}; class FenwickTree { private: std::vector<unsigned> ft; public: FenwickTree(int n) { ft.assign(n + 1, 0); } int rsq(int b) { int sum = 0; for (; b; b -= LSOne(b)) sum += ft[b]; return sum; } // note: LSOne(S) (S & (-S)) int rsq(int a, int b) { return rsq(b) - (a == 1 ? 0 : rsq(a - 1)); } // returns RSQ(a, b) // adjusts value of the k-th element by v (v can be +ve/inc or -ve/dec) void adjust(int k, int v) { // note: n = ft.size() - 1 for (; k < (int)ft.size(); k += LSOne(k)) ft[k] += v; } }; int main() { const unsigned N = GetN(); const unsigned node_id = MyNodeId(); const unsigned range_start = (N / NumberOfNodes()) * (node_id); unsigned range_end = (N / NumberOfNodes()) * (node_id + 1); if (node_id == NumberOfNodes() - 1) range_end = N; for (unsigned i = 0; i < range_start; ++i) ++counting_sort[ GetElement(i) ]; FenwickTree ftree(MAX_ELEM); for (unsigned i = 1; i <= MAX_ELEM; ++i) ftree.adjust(i, counting_sort[i]); ULL inversion_count = 0ULL; for (unsigned i = range_start; i < range_end; ++i) { inversion_count += ftree.rsq( GetElement(i) + 1, MAX_ELEM ); ftree.adjust(GetElement(i), 1); } if (node_id != 0) { PutLL(0, inversion_count); Send(0); } if (node_id == 0) { for (int i = 1; i < NumberOfNodes(); ++i) { Receive(i); inversion_count += GetLL(i); } printf("%llu\n", inversion_count); } return 0; } |