#include "maklib.h" #include "message.h" #include <algorithm> #include <iostream> #include <vector> const int MAIN_NODE = 0; struct result { long long maxsum, maxpref, maxsuf, totalsum; result() : maxsum(0), maxpref(0), maxsuf(0), totalsum(0) { } }; result solve_subarray() { long long curpref = 0, cursum = 0, cursuf = 0; result res; int begin = static_cast<long long>(Size()) * MyNodeId() / NumberOfNodes(); int end = static_cast<long long>(Size()) * (MyNodeId() + 1) / NumberOfNodes(); for(int i = begin; i < end; ++i) { int curval = ElementAt(i + 1); curpref += curval; cursuf -= curval; cursum += curval; if(cursum < 0) cursum = 0; res.maxpref = std::max(res.maxpref, curpref); res.maxsum = std::max(res.maxsum, cursum); res.maxsuf = std::min(res.maxsuf, cursuf); } res.totalsum = curpref; res.maxsuf += res.totalsum; return res; } long long reduce(const std::vector<result> &data) { long long curres = 0, maxres = 0; for(const result &res : data) { /* Optimal segment is contained in res */ maxres = std::max(maxres, res.maxsum); /* Optimal segment ends at res */ maxres = std::max(maxres, curres + res.maxpref); /* Optimal segment contains whole res or only a suffix of it*/ curres = std::max(curres + res.totalsum, res.maxsuf); maxres = std::max(maxres, curres); } return maxres; } void send_result(const result &res) { PutLL(MAIN_NODE, res.maxsum); PutLL(MAIN_NODE, res.maxpref); PutLL(MAIN_NODE, res.maxsuf); PutLL(MAIN_NODE, res.totalsum); Send(MAIN_NODE); } result recv_result(int source) { if(source == MAIN_NODE) return solve_subarray(); else { result res; Receive(source); res.maxsum = GetLL(source); res.maxpref = GetLL(source); res.maxsuf = GetLL(source); res.totalsum = GetLL(source); return res; } } int main() { if(MyNodeId() != MAIN_NODE) { send_result(solve_subarray()); } else { std::vector<result> results(NumberOfNodes()); for(int i = 0; i < NumberOfNodes(); ++i) results[i] = recv_result(i); std::cout << reduce(results) << std::endl; } }
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 | #include "maklib.h" #include "message.h" #include <algorithm> #include <iostream> #include <vector> const int MAIN_NODE = 0; struct result { long long maxsum, maxpref, maxsuf, totalsum; result() : maxsum(0), maxpref(0), maxsuf(0), totalsum(0) { } }; result solve_subarray() { long long curpref = 0, cursum = 0, cursuf = 0; result res; int begin = static_cast<long long>(Size()) * MyNodeId() / NumberOfNodes(); int end = static_cast<long long>(Size()) * (MyNodeId() + 1) / NumberOfNodes(); for(int i = begin; i < end; ++i) { int curval = ElementAt(i + 1); curpref += curval; cursuf -= curval; cursum += curval; if(cursum < 0) cursum = 0; res.maxpref = std::max(res.maxpref, curpref); res.maxsum = std::max(res.maxsum, cursum); res.maxsuf = std::min(res.maxsuf, cursuf); } res.totalsum = curpref; res.maxsuf += res.totalsum; return res; } long long reduce(const std::vector<result> &data) { long long curres = 0, maxres = 0; for(const result &res : data) { /* Optimal segment is contained in res */ maxres = std::max(maxres, res.maxsum); /* Optimal segment ends at res */ maxres = std::max(maxres, curres + res.maxpref); /* Optimal segment contains whole res or only a suffix of it*/ curres = std::max(curres + res.totalsum, res.maxsuf); maxres = std::max(maxres, curres); } return maxres; } void send_result(const result &res) { PutLL(MAIN_NODE, res.maxsum); PutLL(MAIN_NODE, res.maxpref); PutLL(MAIN_NODE, res.maxsuf); PutLL(MAIN_NODE, res.totalsum); Send(MAIN_NODE); } result recv_result(int source) { if(source == MAIN_NODE) return solve_subarray(); else { result res; Receive(source); res.maxsum = GetLL(source); res.maxpref = GetLL(source); res.maxsuf = GetLL(source); res.totalsum = GetLL(source); return res; } } int main() { if(MyNodeId() != MAIN_NODE) { send_result(solve_subarray()); } else { std::vector<result> results(NumberOfNodes()); for(int i = 0; i < NumberOfNodes(); ++i) results[i] = recv_result(i); std::cout << reduce(results) << std::endl; } } |