#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#include "message.h"
#include "maklib.h"
using namespace std;
namespace {
typedef long long LL;
struct Result {
LL offset;
LL smallest;
LL largest;
LL best;
};
const int ELEMENTS_PER_NODE = 1000000;
int NUMBER_OF_NODES;
int ACTIVE_NODES;
int MY_NODE_ID;
int NELEMENTS;
void Initialize() {
ios_base::sync_with_stdio(false); cin.tie(nullptr);
NUMBER_OF_NODES = NumberOfNodes();
MY_NODE_ID = MyNodeId();
NELEMENTS = Size();
ACTIVE_NODES = min((NELEMENTS + ELEMENTS_PER_NODE-1) / ELEMENTS_PER_NODE, NUMBER_OF_NODES);
assert(ACTIVE_NODES >= 1 && ACTIVE_NODES <= NUMBER_OF_NODES);
}
int StartAt(int node) {
return 1 + static_cast<int>(static_cast<LL>(NELEMENTS) * node / ACTIVE_NODES);
}
Result Compute(int a, int b) {
Result res;
res.offset = 0;
res.smallest = 0;
res.largest = 0;
res.best = 0;
for(int i=a;i<b;++i) {
int x = ElementAt(i);
res.offset += x;
res.smallest = min(res.smallest, res.offset);
res.largest = max(res.largest, res.offset);
res.best = max(res.best, res.offset - res.smallest);
}
return res;
}
Result Add(const Result &a, const Result &b) {
Result res;
res.offset = a.offset + b.offset;
res.smallest = min(a.smallest, a.offset + b.smallest);
res.largest = max(a.largest, a.offset + b.largest);
res.best = max(max(a.best, b.best), a.offset + b.largest - a.smallest);
return res;
}
void SendResult(int target, const Result &res) {
PutLL(target, res.offset);
PutLL(target, res.smallest);
PutLL(target, res.largest);
PutLL(target, res.best);
Send(target);
}
Result ReceiveResult(int target) {
int ret = Receive(target);
assert(ret == target);
Result res;
res.offset = GetLL(target);
res.smallest = GetLL(target);
res.largest = GetLL(target);
res.best = GetLL(target);
return res;
}
} // namespace
int main() {
Initialize();
if (MY_NODE_ID>=ACTIVE_NODES) return 0;
Result res = Compute(StartAt(MY_NODE_ID), StartAt(MY_NODE_ID+1));
if (MY_NODE_ID == 0) {
for(int i=1;i<ACTIVE_NODES;++i) {
Result res2 = ReceiveResult(i);
res = Add(res, res2);
}
cout << res.best << '\n';
} else {
SendResult(0, res);
}
}
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 | #include <algorithm> #include <cassert> #include <iostream> #include <vector> #include "message.h" #include "maklib.h" using namespace std; namespace { typedef long long LL; struct Result { LL offset; LL smallest; LL largest; LL best; }; const int ELEMENTS_PER_NODE = 1000000; int NUMBER_OF_NODES; int ACTIVE_NODES; int MY_NODE_ID; int NELEMENTS; void Initialize() { ios_base::sync_with_stdio(false); cin.tie(nullptr); NUMBER_OF_NODES = NumberOfNodes(); MY_NODE_ID = MyNodeId(); NELEMENTS = Size(); ACTIVE_NODES = min((NELEMENTS + ELEMENTS_PER_NODE-1) / ELEMENTS_PER_NODE, NUMBER_OF_NODES); assert(ACTIVE_NODES >= 1 && ACTIVE_NODES <= NUMBER_OF_NODES); } int StartAt(int node) { return 1 + static_cast<int>(static_cast<LL>(NELEMENTS) * node / ACTIVE_NODES); } Result Compute(int a, int b) { Result res; res.offset = 0; res.smallest = 0; res.largest = 0; res.best = 0; for(int i=a;i<b;++i) { int x = ElementAt(i); res.offset += x; res.smallest = min(res.smallest, res.offset); res.largest = max(res.largest, res.offset); res.best = max(res.best, res.offset - res.smallest); } return res; } Result Add(const Result &a, const Result &b) { Result res; res.offset = a.offset + b.offset; res.smallest = min(a.smallest, a.offset + b.smallest); res.largest = max(a.largest, a.offset + b.largest); res.best = max(max(a.best, b.best), a.offset + b.largest - a.smallest); return res; } void SendResult(int target, const Result &res) { PutLL(target, res.offset); PutLL(target, res.smallest); PutLL(target, res.largest); PutLL(target, res.best); Send(target); } Result ReceiveResult(int target) { int ret = Receive(target); assert(ret == target); Result res; res.offset = GetLL(target); res.smallest = GetLL(target); res.largest = GetLL(target); res.best = GetLL(target); return res; } } // namespace int main() { Initialize(); if (MY_NODE_ID>=ACTIVE_NODES) return 0; Result res = Compute(StartAt(MY_NODE_ID), StartAt(MY_NODE_ID+1)); if (MY_NODE_ID == 0) { for(int i=1;i<ACTIVE_NODES;++i) { Result res2 = ReceiveResult(i); res = Add(res, res2); } cout << res.best << '\n'; } else { SendResult(0, res); } } |
English