#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; } |
English