#include <cstdio> #include <stack> #include <algorithm> #include "dzialka.h" #include "message.h" using namespace std; typedef unsigned long long ull_t; int G[75005]; ull_t process_row(int n) { stack<pair<int, int> > S; ull_t possibilities = 0ULL; ull_t sum = 0ULL; for (int i = 0; i <= n; i++) { if (S.empty()) { if (G[i] > 0) { S.push(make_pair(i, G[i])); sum += G[i]; } } else { if (G[i] > S.top().second) { S.push(make_pair(i, G[i])); sum += G[i]; } else if (G[i] == S.top().second) { sum += G[i]; } else { int k; int k_ = i; while (!S.empty() && G[i] < S.top().second) { k = S.top().first; sum -= (k_ - k) * (S.top().second - G[i]); k_ = k; S.pop(); } if ((!S.empty() && G[i] > S.top().second) || (S.empty() && G[i] > 0)) { S.push(make_pair(k, G[i])); } sum += G[i]; } } possibilities += sum; } return possibilities; } int main() { int N = NumberOfNodes(); int M = N/2; int id = MyNodeId(); int h = GetFieldHeight(); int w = GetFieldWidth(); if (id < M) { // i am a reader for (int i = 0; i < h; i++) { int worker_id = M + i % M; for (int j = id; j < w; j += M) { int a = IsUsableCell(i, j); G[j] = a * (G[j] + 1); PutInt(worker_id, G[j]); } } for (int worker_id = M; worker_id < N; worker_id++) { Send(worker_id); } } else { // i am a worker for (int reader_id = 0; reader_id < M; reader_id++) { Receive(reader_id); } ull_t partial_solution = 0ULL; for (int i = id - M; i < h; i += M) { for (int j = 0; j < w; j++) { int reader_id = j % M; G[j] = GetInt(reader_id); } partial_solution += process_row(w); } PutLL(0, partial_solution); Send(0); } if (id == 0) { // i am the master (and a reader as well) ull_t solution = 0ULL; for (int worker_id = M; worker_id < N; worker_id++) { Receive(worker_id); solution += GetLL(worker_id); } printf("%llu\n", solution); } 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 | #include <cstdio> #include <stack> #include <algorithm> #include "dzialka.h" #include "message.h" using namespace std; typedef unsigned long long ull_t; int G[75005]; ull_t process_row(int n) { stack<pair<int, int> > S; ull_t possibilities = 0ULL; ull_t sum = 0ULL; for (int i = 0; i <= n; i++) { if (S.empty()) { if (G[i] > 0) { S.push(make_pair(i, G[i])); sum += G[i]; } } else { if (G[i] > S.top().second) { S.push(make_pair(i, G[i])); sum += G[i]; } else if (G[i] == S.top().second) { sum += G[i]; } else { int k; int k_ = i; while (!S.empty() && G[i] < S.top().second) { k = S.top().first; sum -= (k_ - k) * (S.top().second - G[i]); k_ = k; S.pop(); } if ((!S.empty() && G[i] > S.top().second) || (S.empty() && G[i] > 0)) { S.push(make_pair(k, G[i])); } sum += G[i]; } } possibilities += sum; } return possibilities; } int main() { int N = NumberOfNodes(); int M = N/2; int id = MyNodeId(); int h = GetFieldHeight(); int w = GetFieldWidth(); if (id < M) { // i am a reader for (int i = 0; i < h; i++) { int worker_id = M + i % M; for (int j = id; j < w; j += M) { int a = IsUsableCell(i, j); G[j] = a * (G[j] + 1); PutInt(worker_id, G[j]); } } for (int worker_id = M; worker_id < N; worker_id++) { Send(worker_id); } } else { // i am a worker for (int reader_id = 0; reader_id < M; reader_id++) { Receive(reader_id); } ull_t partial_solution = 0ULL; for (int i = id - M; i < h; i += M) { for (int j = 0; j < w; j++) { int reader_id = j % M; G[j] = GetInt(reader_id); } partial_solution += process_row(w); } PutLL(0, partial_solution); Send(0); } if (id == 0) { // i am the master (and a reader as well) ull_t solution = 0ULL; for (int worker_id = M; worker_id < N; worker_id++) { Receive(worker_id); solution += GetLL(worker_id); } printf("%llu\n", solution); } return 0; } |