#include "dzialka.h" #include "message.h" #include <bits/stdc++.h> using namespace std; #define ST first #define ND second #define MP make_pair typedef pair<int, int> pii; typedef long long int LLI; template<class TH> void _dbg(const char *sdbg, TH h){cerr<<sdbg<<"="<<h<<"\n";} template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) { while(*sdbg!=',')cerr<<*sdbg++;cerr<<"="<<h<<","; _dbg(sdbg+1, a...); } #define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__) const int BlockSize = 750, MX = 75007, msgSize = 10000; int pom[MX], wczesniej[MX], prawo[MX][2]; LLI dp[MX]; int wsk; pii stos[MX]; int main() { const int n = GetFieldHeight(); const int m = GetFieldWidth(); const int ID = MyNodeId(), ile = NumberOfNodes(); int L = ID*BlockSize, R = min(m - 1, (ID+1)*(BlockSize) - 1); if(L > R) return 0; for(int i = 0; i < n; ++i){ int wsk = L - 1; while(wsk < R && IsUsableCell(i, wsk + 1)) ++wsk; pom[i] = wsk - L + 1; } if(R != m - 1){ int cnt = msgSize; for(int i = 0; i < n; ++i){ if(cnt == msgSize){ Receive(ID + 1); cnt = 0; } wczesniej[i] = GetInt(ID + 1); ++cnt; if(pom[i] == R - L + 1) pom[i] += wczesniej[i]; } } if(ID > 0){ int cnt = 0; for(int i = 0; i < n; ++i){ PutInt(ID - 1, pom[i]); ++cnt; if(cnt == msgSize){ Send(ID - 1); cnt = 0; } } if(cnt != 0) Send(ID - 1); } stos[wsk] = MP(-1, n); LLI sumeg = 0; for(int kol = R; kol >= L; --kol){ wsk = 0; for(int w = n - 1; w >= 0; --w){ prawo[w][kol & 1] = (IsUsableCell(w, kol) ? (kol == R ? 1 + wczesniej[w] : 1 + prawo[w][(kol & 1)^1]) : 0); int val = prawo[w][kol & 1]; while(stos[wsk].ST > val) --wsk; int k = stos[wsk].ND - w; dp[w] = LLI(k)*val + dp[w + k]; sumeg += dp[w]; ++wsk; stos[wsk] = MP(val, w); } } if(ID != 0){ PutLL(0, sumeg); Send(0); } if(ID == 0){ for(int i = 1; i*BlockSize < m; ++i){ Receive(i); sumeg += GetLL(i); } cout << sumeg; } }
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 | #include "dzialka.h" #include "message.h" #include <bits/stdc++.h> using namespace std; #define ST first #define ND second #define MP make_pair typedef pair<int, int> pii; typedef long long int LLI; template<class TH> void _dbg(const char *sdbg, TH h){cerr<<sdbg<<"="<<h<<"\n";} template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) { while(*sdbg!=',')cerr<<*sdbg++;cerr<<"="<<h<<","; _dbg(sdbg+1, a...); } #define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__) const int BlockSize = 750, MX = 75007, msgSize = 10000; int pom[MX], wczesniej[MX], prawo[MX][2]; LLI dp[MX]; int wsk; pii stos[MX]; int main() { const int n = GetFieldHeight(); const int m = GetFieldWidth(); const int ID = MyNodeId(), ile = NumberOfNodes(); int L = ID*BlockSize, R = min(m - 1, (ID+1)*(BlockSize) - 1); if(L > R) return 0; for(int i = 0; i < n; ++i){ int wsk = L - 1; while(wsk < R && IsUsableCell(i, wsk + 1)) ++wsk; pom[i] = wsk - L + 1; } if(R != m - 1){ int cnt = msgSize; for(int i = 0; i < n; ++i){ if(cnt == msgSize){ Receive(ID + 1); cnt = 0; } wczesniej[i] = GetInt(ID + 1); ++cnt; if(pom[i] == R - L + 1) pom[i] += wczesniej[i]; } } if(ID > 0){ int cnt = 0; for(int i = 0; i < n; ++i){ PutInt(ID - 1, pom[i]); ++cnt; if(cnt == msgSize){ Send(ID - 1); cnt = 0; } } if(cnt != 0) Send(ID - 1); } stos[wsk] = MP(-1, n); LLI sumeg = 0; for(int kol = R; kol >= L; --kol){ wsk = 0; for(int w = n - 1; w >= 0; --w){ prawo[w][kol & 1] = (IsUsableCell(w, kol) ? (kol == R ? 1 + wczesniej[w] : 1 + prawo[w][(kol & 1)^1]) : 0); int val = prawo[w][kol & 1]; while(stos[wsk].ST > val) --wsk; int k = stos[wsk].ND - w; dp[w] = LLI(k)*val + dp[w + k]; sumeg += dp[w]; ++wsk; stos[wsk] = MP(val, w); } } if(ID != 0){ PutLL(0, sumeg); Send(0); } if(ID == 0){ for(int i = 1; i*BlockSize < m; ++i){ Receive(i); sumeg += GetLL(i); } cout << sumeg; } } |