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