#include <iostream> #include <vector> #include "teatr.h" #include "message.h" using namespace std; #define LL long long int myNodeId; int numberOfNodes; vector<int> elems; vector<int> V; LL answer = 0; int N; vector<int> buf; void countInversionsAndSort(int* l, int* r) { if (r <= l + 1) return; int* mid = l + (r - l) / 2; countInversionsAndSort(l, mid); countInversionsAndSort(mid, r); int* i = &buf[0]; int* i1 = l; int* i2 = mid; while (i1 < mid && i2 < r) { if (*i1 <= *i2) { *(i++) = *(i1++); } else { *(i++) = *(i2++); answer += mid - i1; } } while (i1 < mid) *(i++) = *(i1++); while (i2 < r) *(i++) = *(i2++); while (i2 > l) *(--i2) = *(--i); } inline int fragmentStart(int size, int node) { return (((LL)size) * node) / numberOfNodes; } inline int fragmentEnd(int size, int node) { return fragmentStart(size, node + 1); } void process() { int start = fragmentStart(N, myNodeId); int end = fragmentEnd(N, myNodeId); elems.resize(end - start); buf.resize(end - start); for (int i = start; i < end; ++i) { elems[i - start] = GetElement(i) - 1; } countInversionsAndSort(&elems[0], &elems[0] + (end - start)); V.push_back(0); for (int j = 0; j < end - start; ++j) { while (int(V.size()) - 1 < elems[j]) { V.push_back(V.back()); } ++V.back(); } } void send(int target) { PutLL(target, answer); PutInt(target, V.size()); for (int v: V) PutInt(target, v); Send(target); } void recv(int source) { Receive(source); answer += GetLL(source); int len = GetInt(source); while (V.size() < len) V.push_back(V.back()); int lastX = 0; for (int i = 0; i < len; ++i) { int x = GetInt(source); answer += ((LL)(V.back() - V[i])) * (x - lastX); V[i] += x; lastX = x; } for (int i = len; i < V.size(); ++i) { V[i] += lastX; } } int main() { myNodeId = MyNodeId(); numberOfNodes = NumberOfNodes(); N = GetN(); if (N < numberOfNodes) { numberOfNodes = N; if (myNodeId >= numberOfNodes) { return 0; } } process(); for (int i = 1; i < numberOfNodes; i <<= 1) { if (myNodeId & i) { send(myNodeId ^ i); break; } else { if ((myNodeId ^ i) < numberOfNodes) { recv(myNodeId ^ i); } } } if (myNodeId == 0) { cout << answer; } 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 | #include <iostream> #include <vector> #include "teatr.h" #include "message.h" using namespace std; #define LL long long int myNodeId; int numberOfNodes; vector<int> elems; vector<int> V; LL answer = 0; int N; vector<int> buf; void countInversionsAndSort(int* l, int* r) { if (r <= l + 1) return; int* mid = l + (r - l) / 2; countInversionsAndSort(l, mid); countInversionsAndSort(mid, r); int* i = &buf[0]; int* i1 = l; int* i2 = mid; while (i1 < mid && i2 < r) { if (*i1 <= *i2) { *(i++) = *(i1++); } else { *(i++) = *(i2++); answer += mid - i1; } } while (i1 < mid) *(i++) = *(i1++); while (i2 < r) *(i++) = *(i2++); while (i2 > l) *(--i2) = *(--i); } inline int fragmentStart(int size, int node) { return (((LL)size) * node) / numberOfNodes; } inline int fragmentEnd(int size, int node) { return fragmentStart(size, node + 1); } void process() { int start = fragmentStart(N, myNodeId); int end = fragmentEnd(N, myNodeId); elems.resize(end - start); buf.resize(end - start); for (int i = start; i < end; ++i) { elems[i - start] = GetElement(i) - 1; } countInversionsAndSort(&elems[0], &elems[0] + (end - start)); V.push_back(0); for (int j = 0; j < end - start; ++j) { while (int(V.size()) - 1 < elems[j]) { V.push_back(V.back()); } ++V.back(); } } void send(int target) { PutLL(target, answer); PutInt(target, V.size()); for (int v: V) PutInt(target, v); Send(target); } void recv(int source) { Receive(source); answer += GetLL(source); int len = GetInt(source); while (V.size() < len) V.push_back(V.back()); int lastX = 0; for (int i = 0; i < len; ++i) { int x = GetInt(source); answer += ((LL)(V.back() - V[i])) * (x - lastX); V[i] += x; lastX = x; } for (int i = len; i < V.size(); ++i) { V[i] += lastX; } } int main() { myNodeId = MyNodeId(); numberOfNodes = NumberOfNodes(); N = GetN(); if (N < numberOfNodes) { numberOfNodes = N; if (myNodeId >= numberOfNodes) { return 0; } } process(); for (int i = 1; i < numberOfNodes; i <<= 1) { if (myNodeId & i) { send(myNodeId ^ i); break; } else { if ((myNodeId ^ i) < numberOfNodes) { recv(myNodeId ^ i); } } } if (myNodeId == 0) { cout << answer; } return 0; } |