#include<cstdio>
#include<iostream>
#include<sstream>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<iomanip>
#include<fstream>
#include<ctime>
#include <functional>
#include <pthread.h>
#include <unistd.h>
#include <thread>
#include <mutex>
#include "dzialka.h"
#include "message.h"
using namespace std;
typedef vector<int> VI;
typedef pair <int,int> ii;
typedef long long LL;
typedef pair <ii, LL> iil;
#define pb push_back
const int INF = 2147483647;
using namespace std;
int noOfRowsForMessage = 1000;
int getNoOfColumns(int nodeId, int width, int noOfNodes) {
int noOfColumns = width / noOfNodes;
if (width % noOfNodes > nodeId) noOfColumns++;
return noOfColumns;
}
int find(int bound, vector<iil> &specWek) {
int l = 0;
int r = specWek.size() - 1;
int mid;
while (l < r) {
mid = (l + r) / 2;
if (specWek[mid].first.first <= bound) l = mid + 1; else r = mid;
}
if (specWek[l].first.first > bound) return l;
return -1;
}
int main() {
int i, j, k, last, minn, use, ind;
int nodeId = MyNodeId();
int noOfNodes = NumberOfNodes();
int height = GetFieldHeight();
int width = GetFieldWidth();
int noOfColumns = getNoOfColumns(nodeId, width, noOfNodes);
if (noOfColumns == 0) return 0;
vector<iil> wek[noOfColumns];
vector<iil> specWek;
int startColumn = 0;
for (i = 0;i < nodeId;i++) startColumn += getNoOfColumns(i, width, noOfNodes);
for (i = 0;i < noOfColumns;i++) wek[i].pb(iil(ii(-1, startColumn + i), 0));
specWek.pb(iil(ii(-1, startColumn - 1), 0));
LL res = 0, locRes;
for (i = 0;i < height;i++) {
if (i % noOfRowsForMessage == 0 && startColumn != 0) Receive(nodeId - 1);
last = startColumn == 0 ? -1 : GetInt(nodeId - 1);
while (specWek.size() > 0 && specWek.back().first.second <= last) specWek.pop_back();
locRes = 0;
if (last != startColumn - 1) locRes = (startColumn - 1 - last) * 1LL * (i - specWek.back().first.first) + specWek.back().second;
specWek.push_back(iil(ii(i, last), locRes));
for (j = startColumn;j < startColumn + noOfColumns;j++) {
use = IsUsableCell(i, j);
if (!use) last = j;
if (last >= startColumn) {
while (wek[j - startColumn].size() > 0 && wek[j - startColumn].back().first.second <= last) {
wek[j - startColumn].pop_back();
}
}
locRes = 0;
if (use) {
if (last >= startColumn) {
locRes += (j - last) * 1LL * (i - wek[j - startColumn].back().first.first);
locRes += wek[j - startColumn].back().second;
} else {
ind = find(wek[j - startColumn].back().first.first, specWek);
if (ind == -1) {
locRes += (j - last) * 1LL * (i - wek[j - startColumn].back().first.first);
locRes += wek[j - startColumn].back().second;
} else {
locRes += (specWek.back().second - specWek[ind].second);
locRes += (j - startColumn + 1) * 1LL * (i - specWek[ind].first.first);
locRes += (j - specWek[ind].first.second) * 1LL * (specWek[ind].first.first - wek[j - startColumn].back().first.first);
locRes += wek[j - startColumn].back().second;
}
}
}
if (last >= startColumn) wek[j - startColumn].push_back(iil(ii(i, last), locRes));
res += locRes;
}
if (startColumn + noOfColumns < width) PutInt(nodeId + 1, last);
if (i == height - 1) {
if (startColumn != 0) res += GetLL(nodeId - 1);
if (startColumn + noOfColumns < width) PutLL(nodeId + 1, res); else printf("%lld\n", res);
}
if ((i % noOfRowsForMessage == noOfRowsForMessage - 1 || i == height - 1) && (startColumn + noOfColumns < width)) {
Send(nodeId + 1);
}
}
}
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<cstdio> #include<iostream> #include<sstream> #include<cmath> #include<algorithm> #include<map> #include<set> #include<list> #include<vector> #include<stack> #include<queue> #include<string> #include<iomanip> #include<fstream> #include<ctime> #include <functional> #include <pthread.h> #include <unistd.h> #include <thread> #include <mutex> #include "dzialka.h" #include "message.h" using namespace std; typedef vector<int> VI; typedef pair <int,int> ii; typedef long long LL; typedef pair <ii, LL> iil; #define pb push_back const int INF = 2147483647; using namespace std; int noOfRowsForMessage = 1000; int getNoOfColumns(int nodeId, int width, int noOfNodes) { int noOfColumns = width / noOfNodes; if (width % noOfNodes > nodeId) noOfColumns++; return noOfColumns; } int find(int bound, vector<iil> &specWek) { int l = 0; int r = specWek.size() - 1; int mid; while (l < r) { mid = (l + r) / 2; if (specWek[mid].first.first <= bound) l = mid + 1; else r = mid; } if (specWek[l].first.first > bound) return l; return -1; } int main() { int i, j, k, last, minn, use, ind; int nodeId = MyNodeId(); int noOfNodes = NumberOfNodes(); int height = GetFieldHeight(); int width = GetFieldWidth(); int noOfColumns = getNoOfColumns(nodeId, width, noOfNodes); if (noOfColumns == 0) return 0; vector<iil> wek[noOfColumns]; vector<iil> specWek; int startColumn = 0; for (i = 0;i < nodeId;i++) startColumn += getNoOfColumns(i, width, noOfNodes); for (i = 0;i < noOfColumns;i++) wek[i].pb(iil(ii(-1, startColumn + i), 0)); specWek.pb(iil(ii(-1, startColumn - 1), 0)); LL res = 0, locRes; for (i = 0;i < height;i++) { if (i % noOfRowsForMessage == 0 && startColumn != 0) Receive(nodeId - 1); last = startColumn == 0 ? -1 : GetInt(nodeId - 1); while (specWek.size() > 0 && specWek.back().first.second <= last) specWek.pop_back(); locRes = 0; if (last != startColumn - 1) locRes = (startColumn - 1 - last) * 1LL * (i - specWek.back().first.first) + specWek.back().second; specWek.push_back(iil(ii(i, last), locRes)); for (j = startColumn;j < startColumn + noOfColumns;j++) { use = IsUsableCell(i, j); if (!use) last = j; if (last >= startColumn) { while (wek[j - startColumn].size() > 0 && wek[j - startColumn].back().first.second <= last) { wek[j - startColumn].pop_back(); } } locRes = 0; if (use) { if (last >= startColumn) { locRes += (j - last) * 1LL * (i - wek[j - startColumn].back().first.first); locRes += wek[j - startColumn].back().second; } else { ind = find(wek[j - startColumn].back().first.first, specWek); if (ind == -1) { locRes += (j - last) * 1LL * (i - wek[j - startColumn].back().first.first); locRes += wek[j - startColumn].back().second; } else { locRes += (specWek.back().second - specWek[ind].second); locRes += (j - startColumn + 1) * 1LL * (i - specWek[ind].first.first); locRes += (j - specWek[ind].first.second) * 1LL * (specWek[ind].first.first - wek[j - startColumn].back().first.first); locRes += wek[j - startColumn].back().second; } } } if (last >= startColumn) wek[j - startColumn].push_back(iil(ii(i, last), locRes)); res += locRes; } if (startColumn + noOfColumns < width) PutInt(nodeId + 1, last); if (i == height - 1) { if (startColumn != 0) res += GetLL(nodeId - 1); if (startColumn + noOfColumns < width) PutLL(nodeId + 1, res); else printf("%lld\n", res); } if ((i % noOfRowsForMessage == noOfRowsForMessage - 1 || i == height - 1) && (startColumn + noOfColumns < width)) { Send(nodeId + 1); } } } |
English