#include "dzialka.h" #include "message.h" #define lld long long int #define MAXROWS 75005 #define MAXMESSAGE 16000 #include <cstdio> #include <vector> #include <stack> #include <algorithm> using namespace std; int myId, nodes; int numRows; int numCols; vector<int> lastCol, firstCol; //char data[MAXROWS][751]; /* kroki: 1: oblicz lookLeft lokalnie (lub calosc jesli jest malo) 2: przeslij ostatnia kolumne z lookLeft w prawo do nastepnyj maszyny (łańcuszkiem) 3: zaktualizuj lookLeft globalnie 4: obliczaj wyniki dla każdej maszyny na swoim kawałku pola 5: zbierz wyniki do 0 */ int main() { myId = MyNodeId(); nodes = NumberOfNodes(); numRows = GetFieldHeight(); numCols = GetFieldWidth(); bool singleNode = numCols < nodes; // if so use all machines, otherwise just 0 if (singleNode && myId) return 0; // from now on nodes 1+ are dead, if singleNode we can assume it's only node 0 int from, to, c; lld result = 0; if (singleNode) { from = 0; to = numCols; } else { from = (myId * numCols) / nodes; to = ((myId + 1) * numCols) / nodes; } c = to - from; // generating lastCol.resize(numRows); firstCol.resize(numRows); for (int i = 0; i < numRows; i++) { int lastVal = IsUsableCell(i, from); lastCol[i] = lastVal; firstCol[i] = lastVal; for (int j = from + 1; j < to; j++) { lastVal = IsUsableCell(i, j) ? lastVal + 1 : 0; lastCol[i] = lastVal; } } if (!singleNode) { if (myId != 0) { // receive last column and first and last column Receive(myId - 1); for (int i = 0; i < numRows; i++) { if (i % MAXMESSAGE == MAXMESSAGE - 1) { Receive(myId - 1); } int a = GetInt(myId - 1); if (firstCol[i]) { firstCol[i] += a; } if (lastCol[i] == c) { lastCol[i] = c + a; } } } if (myId != nodes - 1) { // send last columt further right for (int i = 0; i < numRows; i++) { if (i % MAXMESSAGE == MAXMESSAGE - 1) { Send(myId + 1); } PutInt(myId + 1, lastCol[i]); } Send(myId + 1); } } for (int j = from; j < to; j++) { if (j > from) { for (int i = 0; i < numRows; i++) { int lastVal = IsUsableCell(i, j); if (lastVal) { firstCol[i] = firstCol[i] + 1; } else { firstCol[i] = 0; } } } stack<pair<int,int>> st; // [left, top] lld stackArea = 0; st.push(make_pair(0, -1)); for (int i = 0; i < numRows; i++) { int l = firstCol[i]; if (l) { pair<int, int> g = make_pair(l, i); while (st.top().first > l) { pair<int,int> h = st.top(); st.pop(); stackArea -= (h.first - l) * (g.second - h.second); g = h; } if (l > st.top().first) { g.first = l; st.push(g); } stackArea += l; result += stackArea; } else { while(!st.empty()) st.pop(); stackArea = 0; st.push(make_pair(0, i)); } } } if (singleNode) { printf("%lld\n", result); } else { long long int RESULT = result; if (myId == 0) { for (int i = 1; i < nodes; i++) { Receive(i); RESULT += GetLL(i); } printf("%lld\n", RESULT); } else { PutLL(0, result); Send(0); } } 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 | #include "dzialka.h" #include "message.h" #define lld long long int #define MAXROWS 75005 #define MAXMESSAGE 16000 #include <cstdio> #include <vector> #include <stack> #include <algorithm> using namespace std; int myId, nodes; int numRows; int numCols; vector<int> lastCol, firstCol; //char data[MAXROWS][751]; /* kroki: 1: oblicz lookLeft lokalnie (lub calosc jesli jest malo) 2: przeslij ostatnia kolumne z lookLeft w prawo do nastepnyj maszyny (łańcuszkiem) 3: zaktualizuj lookLeft globalnie 4: obliczaj wyniki dla każdej maszyny na swoim kawałku pola 5: zbierz wyniki do 0 */ int main() { myId = MyNodeId(); nodes = NumberOfNodes(); numRows = GetFieldHeight(); numCols = GetFieldWidth(); bool singleNode = numCols < nodes; // if so use all machines, otherwise just 0 if (singleNode && myId) return 0; // from now on nodes 1+ are dead, if singleNode we can assume it's only node 0 int from, to, c; lld result = 0; if (singleNode) { from = 0; to = numCols; } else { from = (myId * numCols) / nodes; to = ((myId + 1) * numCols) / nodes; } c = to - from; // generating lastCol.resize(numRows); firstCol.resize(numRows); for (int i = 0; i < numRows; i++) { int lastVal = IsUsableCell(i, from); lastCol[i] = lastVal; firstCol[i] = lastVal; for (int j = from + 1; j < to; j++) { lastVal = IsUsableCell(i, j) ? lastVal + 1 : 0; lastCol[i] = lastVal; } } if (!singleNode) { if (myId != 0) { // receive last column and first and last column Receive(myId - 1); for (int i = 0; i < numRows; i++) { if (i % MAXMESSAGE == MAXMESSAGE - 1) { Receive(myId - 1); } int a = GetInt(myId - 1); if (firstCol[i]) { firstCol[i] += a; } if (lastCol[i] == c) { lastCol[i] = c + a; } } } if (myId != nodes - 1) { // send last columt further right for (int i = 0; i < numRows; i++) { if (i % MAXMESSAGE == MAXMESSAGE - 1) { Send(myId + 1); } PutInt(myId + 1, lastCol[i]); } Send(myId + 1); } } for (int j = from; j < to; j++) { if (j > from) { for (int i = 0; i < numRows; i++) { int lastVal = IsUsableCell(i, j); if (lastVal) { firstCol[i] = firstCol[i] + 1; } else { firstCol[i] = 0; } } } stack<pair<int,int>> st; // [left, top] lld stackArea = 0; st.push(make_pair(0, -1)); for (int i = 0; i < numRows; i++) { int l = firstCol[i]; if (l) { pair<int, int> g = make_pair(l, i); while (st.top().first > l) { pair<int,int> h = st.top(); st.pop(); stackArea -= (h.first - l) * (g.second - h.second); g = h; } if (l > st.top().first) { g.first = l; st.push(g); } stackArea += l; result += stackArea; } else { while(!st.empty()) st.pop(); stackArea = 0; st.push(make_pair(0, i)); } } } if (singleNode) { printf("%lld\n", result); } else { long long int RESULT = result; if (myId == 0) { for (int i = 1; i < nodes; i++) { Receive(i); RESULT += GetLL(i); } printf("%lld\n", RESULT); } else { PutLL(0, result); Send(0); } } return 0; } |