#include <bits/stdc++.h> #include "message.h" #include "kanapka.h" struct partial_answer { long long prefix_min; long long suffix_min; long long absolute_min; long long total; }; template <typename T> void minimize(T& x, T value) { if (value < x) x = value; } partial_answer calculate_for(long long l, long long r) { long long prefix_min = GetTaste(l); long long suffix_min = GetTaste(r); long long total = 0LL; for (long long i = l; i <= r; i++) { total += GetTaste(i); minimize(prefix_min, total); } total = 0LL; for (long long i = r; i >= l; i--) { total += GetTaste(i); minimize(suffix_min, total); } long long absolute_min = 0LL; long long current_min = 0LL; for (long long i = l; i <= r; i++) { long long cur_value = GetTaste(i); current_min += cur_value; minimize(current_min, 0LL); minimize(absolute_min, current_min); } return { prefix_min, suffix_min, absolute_min, total }; } int main() { long long n = GetN(); if (n <= 2 * NumberOfNodes()) { if (MyNodeId() == 0) { auto answer = calculate_for(0, n - 1); std::cout << answer.total - answer.absolute_min << std::endl; } return 0; } long long myL = n / NumberOfNodes() * MyNodeId(); long long myR; if (MyNodeId() == NumberOfNodes() - 1) { myR = n - 1; } else { myR = n / NumberOfNodes() * (MyNodeId() + 1) - 1; } partial_answer myAnswer = calculate_for(myL, myR); PutLL(0, myAnswer.prefix_min); PutLL(0, myAnswer.suffix_min); PutLL(0, myAnswer.absolute_min); PutLL(0, myAnswer.total); Send(0); if (MyNodeId() == 0) { std::vector<partial_answer> partial_answers(NumberOfNodes()); for (int node = 0; node < NumberOfNodes(); node++) { Receive(node); partial_answers.push_back({ GetLL(node), GetLL(node), GetLL(node), GetLL(node) }); } long long total = 0LL; for (auto p: partial_answers) total += p.total; long long minimum_segment = 0LL; for (auto p: partial_answers) minimize(minimum_segment, p.absolute_min); for (int i = 0; i < partial_answers.size(); i++) { long long middle_total = 0LL; for (int j = i + 1; j < partial_answers.size(); j++) { minimize(minimum_segment, partial_answers[i].suffix_min + middle_total + partial_answers[j].prefix_min); middle_total += partial_answers[j].total; } } std::cout << total - minimum_segment << 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 96 97 98 | #include <bits/stdc++.h> #include "message.h" #include "kanapka.h" struct partial_answer { long long prefix_min; long long suffix_min; long long absolute_min; long long total; }; template <typename T> void minimize(T& x, T value) { if (value < x) x = value; } partial_answer calculate_for(long long l, long long r) { long long prefix_min = GetTaste(l); long long suffix_min = GetTaste(r); long long total = 0LL; for (long long i = l; i <= r; i++) { total += GetTaste(i); minimize(prefix_min, total); } total = 0LL; for (long long i = r; i >= l; i--) { total += GetTaste(i); minimize(suffix_min, total); } long long absolute_min = 0LL; long long current_min = 0LL; for (long long i = l; i <= r; i++) { long long cur_value = GetTaste(i); current_min += cur_value; minimize(current_min, 0LL); minimize(absolute_min, current_min); } return { prefix_min, suffix_min, absolute_min, total }; } int main() { long long n = GetN(); if (n <= 2 * NumberOfNodes()) { if (MyNodeId() == 0) { auto answer = calculate_for(0, n - 1); std::cout << answer.total - answer.absolute_min << std::endl; } return 0; } long long myL = n / NumberOfNodes() * MyNodeId(); long long myR; if (MyNodeId() == NumberOfNodes() - 1) { myR = n - 1; } else { myR = n / NumberOfNodes() * (MyNodeId() + 1) - 1; } partial_answer myAnswer = calculate_for(myL, myR); PutLL(0, myAnswer.prefix_min); PutLL(0, myAnswer.suffix_min); PutLL(0, myAnswer.absolute_min); PutLL(0, myAnswer.total); Send(0); if (MyNodeId() == 0) { std::vector<partial_answer> partial_answers(NumberOfNodes()); for (int node = 0; node < NumberOfNodes(); node++) { Receive(node); partial_answers.push_back({ GetLL(node), GetLL(node), GetLL(node), GetLL(node) }); } long long total = 0LL; for (auto p: partial_answers) total += p.total; long long minimum_segment = 0LL; for (auto p: partial_answers) minimize(minimum_segment, p.absolute_min); for (int i = 0; i < partial_answers.size(); i++) { long long middle_total = 0LL; for (int j = i + 1; j < partial_answers.size(); j++) { minimize(minimum_segment, partial_answers[i].suffix_min + middle_total + partial_answers[j].prefix_min); middle_total += partial_answers[j].total; } } std::cout << total - minimum_segment << std::endl; } } |