#include <cstdio>
#include "message.h"
#include "maklib.h"
typedef long long ll;
template <typename T, T (*assocFun)(T, T), T (*getFun)(int), void (*putFun)(int, T)>
T computeInZero(T localVal) {
int mask = 1;
T val = localVal;
while (mask < NumberOfNodes()) {
int partner = MyNodeId() ^ mask;
if (MyNodeId() % (2 * mask) == mask) {
putFun(partner, val);
Send(partner);
} else if (MyNodeId() % (2 * mask) == 0 && partner < NumberOfNodes()) {
Receive(partner);
T extVal = getFun(partner);
val = assocFun(val, extVal);
}
mask *= 2;
}
return val;
}
/*
template <typename T, T *getFun(int), void *putFun(int, T)>
T propagate(T zeroVal) {
do {
mask >>= 1;
if (MyNodeId() % (2 * mask) == mask) {
int source = MyNodeId() ^ mask;
Receive(source);
val = getFun(source);
} else if (MyNodeId() % (2 * mask) == 0 && MyNodeId() ^ mask < NumberOfNodes()) {
int target = MyNodeId() ^ mask;
putFun(target, val);
Send(target);
}
} while (mask > 1);
}
*/
template <typename T, T (*assocFun)(T, T), T (*getFun)(int), void (*putFun)(int, T)>
T computeInAll(T localVal) {
int mask = 1;
T val = localVal;
while (mask < NumberOfNodes()) {
if (MyNodeId() % (2 * mask) == mask - 1 && MyNodeId() + mask < NumberOfNodes()) {
int target = MyNodeId() + mask;
putFun(target, val);
Send(target);
} else if (MyNodeId() % (2 * mask) == 2 * mask - 1) {
int source = MyNodeId() - mask;
Receive(source);
T extVal = getFun(source);
val = assocFun(extVal, val);
}
mask *= 2;
}
while (mask > 2) {
mask /= 2;
if (MyNodeId() % mask == mask - 1 && MyNodeId() + mask / 2 < NumberOfNodes()) {
int target = MyNodeId() + mask / 2;
putFun(target, val);
Send(target);
} else if (MyNodeId() % mask == mask / 2 - 1 && MyNodeId() >= mask / 2) {
int source = MyNodeId() - mask / 2;
Receive(source);
T extVal = getFun(source);
val = assocFun(extVal, val);
}
}
return val;
}
ll add(ll a, ll b) {
return a + b;
}
ll minimum(ll a, ll b) {
return a < b ? a : b;
}
ll maximum(ll a, ll b) {
return a < b ? b : a;
}
int main() {
ll localSum = 0;
ll minLocalSum = 0;
ll begin = (ll)Size() * MyNodeId() / NumberOfNodes() + 1;
ll end = (ll)Size() * (MyNodeId() + 1) / NumberOfNodes() + 1;
for (ll i = begin; i < end; ++i) {
localSum += ElementAt(i);
if (localSum < minLocalSum) {
minLocalSum = localSum;
}
}
ll totalSum = computeInAll<ll, add, GetLL, PutLL>(localSum);
ll prevSum = totalSum - localSum;
minLocalSum += prevSum;
ll prevMinLocalSum = 0;
if (MyNodeId() != NumberOfNodes() - 1) {
PutLL(MyNodeId() + 1, minLocalSum);
Send(MyNodeId() + 1);
}
if (MyNodeId() != 0) {
Receive(MyNodeId() - 1);
prevMinLocalSum = GetLL(MyNodeId() - 1);
}
ll prevMinSum = computeInAll<ll, minimum, GetLL, PutLL>(prevMinLocalSum);
ll sum = prevSum;
ll minSum = prevMinSum;
ll maxResult = 0;
for (ll i = begin; i < end; ++i) {
sum += ElementAt(i);
if (sum < minSum) {
minSum = sum;
} else if (sum - minSum > maxResult) {
maxResult = sum - minSum;
}
}
ll totalMaxResult = computeInZero<ll, maximum, GetLL, PutLL>(maxResult);
if (MyNodeId() == 0) {
printf("%lld\n", totalMaxResult);
}
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #include <cstdio> #include "message.h" #include "maklib.h" typedef long long ll; template <typename T, T (*assocFun)(T, T), T (*getFun)(int), void (*putFun)(int, T)> T computeInZero(T localVal) { int mask = 1; T val = localVal; while (mask < NumberOfNodes()) { int partner = MyNodeId() ^ mask; if (MyNodeId() % (2 * mask) == mask) { putFun(partner, val); Send(partner); } else if (MyNodeId() % (2 * mask) == 0 && partner < NumberOfNodes()) { Receive(partner); T extVal = getFun(partner); val = assocFun(val, extVal); } mask *= 2; } return val; } /* template <typename T, T *getFun(int), void *putFun(int, T)> T propagate(T zeroVal) { do { mask >>= 1; if (MyNodeId() % (2 * mask) == mask) { int source = MyNodeId() ^ mask; Receive(source); val = getFun(source); } else if (MyNodeId() % (2 * mask) == 0 && MyNodeId() ^ mask < NumberOfNodes()) { int target = MyNodeId() ^ mask; putFun(target, val); Send(target); } } while (mask > 1); } */ template <typename T, T (*assocFun)(T, T), T (*getFun)(int), void (*putFun)(int, T)> T computeInAll(T localVal) { int mask = 1; T val = localVal; while (mask < NumberOfNodes()) { if (MyNodeId() % (2 * mask) == mask - 1 && MyNodeId() + mask < NumberOfNodes()) { int target = MyNodeId() + mask; putFun(target, val); Send(target); } else if (MyNodeId() % (2 * mask) == 2 * mask - 1) { int source = MyNodeId() - mask; Receive(source); T extVal = getFun(source); val = assocFun(extVal, val); } mask *= 2; } while (mask > 2) { mask /= 2; if (MyNodeId() % mask == mask - 1 && MyNodeId() + mask / 2 < NumberOfNodes()) { int target = MyNodeId() + mask / 2; putFun(target, val); Send(target); } else if (MyNodeId() % mask == mask / 2 - 1 && MyNodeId() >= mask / 2) { int source = MyNodeId() - mask / 2; Receive(source); T extVal = getFun(source); val = assocFun(extVal, val); } } return val; } ll add(ll a, ll b) { return a + b; } ll minimum(ll a, ll b) { return a < b ? a : b; } ll maximum(ll a, ll b) { return a < b ? b : a; } int main() { ll localSum = 0; ll minLocalSum = 0; ll begin = (ll)Size() * MyNodeId() / NumberOfNodes() + 1; ll end = (ll)Size() * (MyNodeId() + 1) / NumberOfNodes() + 1; for (ll i = begin; i < end; ++i) { localSum += ElementAt(i); if (localSum < minLocalSum) { minLocalSum = localSum; } } ll totalSum = computeInAll<ll, add, GetLL, PutLL>(localSum); ll prevSum = totalSum - localSum; minLocalSum += prevSum; ll prevMinLocalSum = 0; if (MyNodeId() != NumberOfNodes() - 1) { PutLL(MyNodeId() + 1, minLocalSum); Send(MyNodeId() + 1); } if (MyNodeId() != 0) { Receive(MyNodeId() - 1); prevMinLocalSum = GetLL(MyNodeId() - 1); } ll prevMinSum = computeInAll<ll, minimum, GetLL, PutLL>(prevMinLocalSum); ll sum = prevSum; ll minSum = prevMinSum; ll maxResult = 0; for (ll i = begin; i < end; ++i) { sum += ElementAt(i); if (sum < minSum) { minSum = sum; } else if (sum - minSum > maxResult) { maxResult = sum - minSum; } } ll totalMaxResult = computeInZero<ll, maximum, GetLL, PutLL>(maxResult); if (MyNodeId() == 0) { printf("%lld\n", totalMaxResult); } return 0; } |
English