#include "dzialka.h" #include "message.h" #include <cstdio> #include <vector> using namespace std; typedef long long LL; const int inf = 1000000000; bool t[75005][755]; int l[75005]; int L[75005]; pair<int, int> stack[75005]; int main() { int id = MyNodeId(); int W = GetFieldWidth(); int T = NumberOfNodes(); int N = GetFieldHeight(); int M = (W+T-1) / T; int begins_at = id * M; if(begins_at >= W) M = 0; else if(begins_at+M > W) M = W-begins_at; for(int i = 0; i < N; i++) { l[i] = -1; for(int j = 0; j < M; j++) { t[i][j] = !IsUsableCell(i, j+begins_at); if(t[i][j]) l[i] = j; } } if(id != 0) { int c = 0; Receive(id-1); for(int i = 0; i < N; i++) { if(c == 15000) { c = 0; Receive(id-1); } L[i] = GetInt(id-1); c++; } } else { for(int i = 0; i < N; i++) L[i] = -1; } if(id != T-1) { int c = 0; for(int i = 0; i < N; i++) { c++; if(l[i] == -1) PutInt(id+1, L[i]-M); else PutInt(id+1, l[i]-M); if(c == 15000) { c = 0; Send(id+1); } } if(c != 0) Send(id+1); } LL ans = 0; for(int j = 0; j < M; j++) { stack[0] = {-1, inf}; int head = 1; LL w = 0; for(int i = 0; i < N; i++) { if(t[i][j]) { head = 1; stack[0].first = i; L[i] = j; w = 0; } else { while(stack[head-1].second < L[i]) { w -= LL(j-stack[head-1].second)*(stack[head-1].first-stack[head-2].first); head--; } w += LL(j-L[i])*(i-stack[head-1].first); stack[head++] = {i, L[i]}; ans += w; } } } if(id != 0) { PutLL(0, ans); Send(0); } else { for(int i = 1; i < T; i++) { Receive(i); ans += GetLL(i); } printf("%lli\n", ans); } }
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 110 111 112 113 | #include "dzialka.h" #include "message.h" #include <cstdio> #include <vector> using namespace std; typedef long long LL; const int inf = 1000000000; bool t[75005][755]; int l[75005]; int L[75005]; pair<int, int> stack[75005]; int main() { int id = MyNodeId(); int W = GetFieldWidth(); int T = NumberOfNodes(); int N = GetFieldHeight(); int M = (W+T-1) / T; int begins_at = id * M; if(begins_at >= W) M = 0; else if(begins_at+M > W) M = W-begins_at; for(int i = 0; i < N; i++) { l[i] = -1; for(int j = 0; j < M; j++) { t[i][j] = !IsUsableCell(i, j+begins_at); if(t[i][j]) l[i] = j; } } if(id != 0) { int c = 0; Receive(id-1); for(int i = 0; i < N; i++) { if(c == 15000) { c = 0; Receive(id-1); } L[i] = GetInt(id-1); c++; } } else { for(int i = 0; i < N; i++) L[i] = -1; } if(id != T-1) { int c = 0; for(int i = 0; i < N; i++) { c++; if(l[i] == -1) PutInt(id+1, L[i]-M); else PutInt(id+1, l[i]-M); if(c == 15000) { c = 0; Send(id+1); } } if(c != 0) Send(id+1); } LL ans = 0; for(int j = 0; j < M; j++) { stack[0] = {-1, inf}; int head = 1; LL w = 0; for(int i = 0; i < N; i++) { if(t[i][j]) { head = 1; stack[0].first = i; L[i] = j; w = 0; } else { while(stack[head-1].second < L[i]) { w -= LL(j-stack[head-1].second)*(stack[head-1].first-stack[head-2].first); head--; } w += LL(j-L[i])*(i-stack[head-1].first); stack[head++] = {i, L[i]}; ans += w; } } } if(id != 0) { PutLL(0, ans); Send(0); } else { for(int i = 1; i < T; i++) { Receive(i); ans += GetLL(i); } printf("%lli\n", ans); } } |