#include "dzialka.h"
#include "message.h"
#include <cstdio>
#include <cstdlib>
#define ul unsigned long long
#define ll long long
int depth[77777];
int s1[77777];
int s2[77777];
ul bh, bw;
ul sum3(ul len, ul g) {
return len*(len+1)/2*g;
}
ul solveSequential(int offH, int offW, int h, int w) {
int zh = offH + h;
int zw = offW + w;
ul res = 0;
for(int i=0;i<h;i++) {
int ii = i + offH;
for(int j=0;j<w;j++) {
int jj = j + offW;
if((ii < bh) && (jj < bw)) {
if(IsUsableCell(ii,jj)) {
depth[j]++;
} else {
depth[j]=0;
}
} else {
depth[j] = 0;
}
}
int us = 0;
for(int j=0;j<=w;j++) {
bool p = false;
int k = 0;
int g = 0;
if(us > 0) {
k = s1[us-1];
g = s2[us-1];
}
int prevK = -1;
ul len = 0;
while(us > 0 && (g > depth[j])) {
len = j-k;
ul cur = sum3(len,g);
res += cur;
if(prevK != -1) {
res -= sum3(j-prevK,g);
}
us--;
prevK = k;
p = true;
if(us > 0) {
k = s1[us-1];
g = s2[us-1];
}
}
if(p) {
if(depth[j] > 0) {
res -= sum3(len,depth[j]);
}
}
if(((us==0) && (depth[j] > 0)) || (g < depth[j])) {
s1[us] = p?prevK:j;
s2[us] = depth[j];
us++;
}
}
}
return res;
}
int main(int argc, char** argv) {
bh = GetFieldHeight();
bw = GetFieldWidth();
int mi = (bh < bw) ? bh : bw;
if(mi < 4000) {
if(MyNodeId() == 0) {
ul res = solveSequential(0,0,bh,bw);
printf("%llu\n", res);
}
} else {
int nodes = NumberOfNodes();
int chunk = bw/nodes;
if((bw%nodes)!=0) {
chunk++;
}
int me = MyNodeId();
int start = me * chunk;
int end = (me+1)*chunk;
ll res = (ll)solveSequential(0,start,bh,chunk);
if(me != 0) {
PutLL(0,res);
Send(0);
} else {
for(int i=1;i<nodes;i++) {
Receive(i);
res += GetLL(i);
}
printf("%lld\n", res);
}
}
}
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 | #include "dzialka.h" #include "message.h" #include <cstdio> #include <cstdlib> #define ul unsigned long long #define ll long long int depth[77777]; int s1[77777]; int s2[77777]; ul bh, bw; ul sum3(ul len, ul g) { return len*(len+1)/2*g; } ul solveSequential(int offH, int offW, int h, int w) { int zh = offH + h; int zw = offW + w; ul res = 0; for(int i=0;i<h;i++) { int ii = i + offH; for(int j=0;j<w;j++) { int jj = j + offW; if((ii < bh) && (jj < bw)) { if(IsUsableCell(ii,jj)) { depth[j]++; } else { depth[j]=0; } } else { depth[j] = 0; } } int us = 0; for(int j=0;j<=w;j++) { bool p = false; int k = 0; int g = 0; if(us > 0) { k = s1[us-1]; g = s2[us-1]; } int prevK = -1; ul len = 0; while(us > 0 && (g > depth[j])) { len = j-k; ul cur = sum3(len,g); res += cur; if(prevK != -1) { res -= sum3(j-prevK,g); } us--; prevK = k; p = true; if(us > 0) { k = s1[us-1]; g = s2[us-1]; } } if(p) { if(depth[j] > 0) { res -= sum3(len,depth[j]); } } if(((us==0) && (depth[j] > 0)) || (g < depth[j])) { s1[us] = p?prevK:j; s2[us] = depth[j]; us++; } } } return res; } int main(int argc, char** argv) { bh = GetFieldHeight(); bw = GetFieldWidth(); int mi = (bh < bw) ? bh : bw; if(mi < 4000) { if(MyNodeId() == 0) { ul res = solveSequential(0,0,bh,bw); printf("%llu\n", res); } } else { int nodes = NumberOfNodes(); int chunk = bw/nodes; if((bw%nodes)!=0) { chunk++; } int me = MyNodeId(); int start = me * chunk; int end = (me+1)*chunk; ll res = (ll)solveSequential(0,start,bh,chunk); if(me != 0) { PutLL(0,res); Send(0); } else { for(int i=1;i<nodes;i++) { Receive(i); res += GetLL(i); } printf("%lld\n", res); } } } |
English