#include <bits/stdc++.h> #include "dzialka.h" #include "message.h" using namespace std; typedef long long ll; typedef unsigned long long llu; int n, m, nodes, mynode; int which_node_x[75007], which_node_y[75007]; int mynode_x1, mynode_x2, mynode_y1, mynode_y2; int M[75007], l[75007], r[75007]; stack<int> S; int main() { n = GetFieldHeight(); m = GetFieldWidth(); nodes = NumberOfNodes(); mynode = MyNodeId(); int for_node = int(ceil(double(n) / double(nodes))); int a = 0, xnodes = nodes; for(int i = 0 ; i < nodes ; i++) { if(a >= n) { xnodes = i; break; } int b = a; which_node_x[b] = i; while(b - a + 2 <= for_node && b < n - 1) { b++; which_node_x[b] = i; } if(i == mynode) { mynode_x1 = a; mynode_x2 = b; } a = b + 1; } for_node = int(ceil(double(m) / double(nodes))); a = 0; int ynodes = nodes; for(int i = 0 ; i < nodes ; i++) { if(a >= m) { ynodes = i; break; } int b = a; which_node_y[b] = i; while(b - a + 2 <= for_node && b < m - 1) { b++; which_node_y[b] = i; } if(i == mynode) { mynode_y1 = a; mynode_y2 = b; } a = b + 1; } if(mynode < xnodes) { for(int x = mynode_x1 ; x <= mynode_x2 ; x++) { for(int y = 0 ; y < m ; y++) M[y] = IsUsableCell(x, y); for(int y = m ; y >= 0 ; y--) if(y == m || M[y] == 0) for(int y2 = y - 1 ; y2 >= 0 && M[y2] ; y2--) M[y2] = M[y2 + 1] + 1; for(int y = 0 ; y < m ; y++) if(y == m - 1 || which_node_y[y] != which_node_y[y + 1]) PutInt(which_node_y[y], M[y]); } for(int i = 0 ; i < ynodes ; i++) Send(i); } if(mynode < ynodes) { ll res = 0; for(int i = 0 ; i < xnodes ; i++) Receive(i); for(int x = 0 ; x < n ; x++) M[x] = GetInt(which_node_x[x]); for(int y = mynode_y2 ; y >= mynode_y1 ; y--) { for(int x = 0 ; x < n ; x++) { while(!S.empty() && M[S.top()] > M[x]) { r[S.top()] = x; S.pop(); } S.push(x); } while(!S.empty()) { r[S.top()] = n; S.pop(); } for(int x = n - 1 ; x >= 0 ; x--) { while(!S.empty() && M[S.top()] >= M[x]) { l[S.top()] = x; S.pop(); } S.push(x); } while(!S.empty()) { l[S.top()] = -1; S.pop(); } for(int x = 0 ; x < n ; x++) { res += ll(x - l[x]) * ll(r[x] - x) * ll(M[x]); } if(y > mynode_y1) { for(int x = 0 ; x < n ; x++) { if(!IsUsableCell(x, y - 1)) M[x] = 0; else M[x]++; } } } PutLL(0, res); Send(0); } if(mynode == 0) { llu res = 0; for(int i = 0 ; i < ynodes ; i++) { Receive(i); res += llu(GetLL(i)); } printf("%llu\n", res); } 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #include <bits/stdc++.h> #include "dzialka.h" #include "message.h" using namespace std; typedef long long ll; typedef unsigned long long llu; int n, m, nodes, mynode; int which_node_x[75007], which_node_y[75007]; int mynode_x1, mynode_x2, mynode_y1, mynode_y2; int M[75007], l[75007], r[75007]; stack<int> S; int main() { n = GetFieldHeight(); m = GetFieldWidth(); nodes = NumberOfNodes(); mynode = MyNodeId(); int for_node = int(ceil(double(n) / double(nodes))); int a = 0, xnodes = nodes; for(int i = 0 ; i < nodes ; i++) { if(a >= n) { xnodes = i; break; } int b = a; which_node_x[b] = i; while(b - a + 2 <= for_node && b < n - 1) { b++; which_node_x[b] = i; } if(i == mynode) { mynode_x1 = a; mynode_x2 = b; } a = b + 1; } for_node = int(ceil(double(m) / double(nodes))); a = 0; int ynodes = nodes; for(int i = 0 ; i < nodes ; i++) { if(a >= m) { ynodes = i; break; } int b = a; which_node_y[b] = i; while(b - a + 2 <= for_node && b < m - 1) { b++; which_node_y[b] = i; } if(i == mynode) { mynode_y1 = a; mynode_y2 = b; } a = b + 1; } if(mynode < xnodes) { for(int x = mynode_x1 ; x <= mynode_x2 ; x++) { for(int y = 0 ; y < m ; y++) M[y] = IsUsableCell(x, y); for(int y = m ; y >= 0 ; y--) if(y == m || M[y] == 0) for(int y2 = y - 1 ; y2 >= 0 && M[y2] ; y2--) M[y2] = M[y2 + 1] + 1; for(int y = 0 ; y < m ; y++) if(y == m - 1 || which_node_y[y] != which_node_y[y + 1]) PutInt(which_node_y[y], M[y]); } for(int i = 0 ; i < ynodes ; i++) Send(i); } if(mynode < ynodes) { ll res = 0; for(int i = 0 ; i < xnodes ; i++) Receive(i); for(int x = 0 ; x < n ; x++) M[x] = GetInt(which_node_x[x]); for(int y = mynode_y2 ; y >= mynode_y1 ; y--) { for(int x = 0 ; x < n ; x++) { while(!S.empty() && M[S.top()] > M[x]) { r[S.top()] = x; S.pop(); } S.push(x); } while(!S.empty()) { r[S.top()] = n; S.pop(); } for(int x = n - 1 ; x >= 0 ; x--) { while(!S.empty() && M[S.top()] >= M[x]) { l[S.top()] = x; S.pop(); } S.push(x); } while(!S.empty()) { l[S.top()] = -1; S.pop(); } for(int x = 0 ; x < n ; x++) { res += ll(x - l[x]) * ll(r[x] - x) * ll(M[x]); } if(y > mynode_y1) { for(int x = 0 ; x < n ; x++) { if(!IsUsableCell(x, y - 1)) M[x] = 0; else M[x]++; } } } PutLL(0, res); Send(0); } if(mynode == 0) { llu res = 0; for(int i = 0 ; i < ynodes ; i++) { Receive(i); res += llu(GetLL(i)); } printf("%llu\n", res); } return 0; } |