#include <bits/stdc++.h> #include "message.h" #include "krazki.h" using namespace std; typedef long long LL; const LL INF = 1e18 + 7; const LL N = 1007; LL n, m, k, id; LL s[N], e[N]; LL MN[N], MX[N], T[N], G[N], ans[N]; vector < LL > V; int main() { n = PipeHeight(); m = NumberOfDiscs(); k = NumberOfNodes(); id = MyNodeId(); if(m > n) { if(MyNodeId() == 0) puts("0"); return 0; } LL cp = n; while(cp % k) cp++; for(LL i = 0; i < k; i++) s[i] = i * cp / k + 1, e[i] = (i + 1) * cp / k + 1; LL mn = INF, mx; s[id] > n ? mx = 0 : mx = HoleDiameter(s[id]); //printf("%lld\n", id); //printf("%lld %lld\n", s, e); for(LL i = s[id]; i < e[id]; i++) { if(i > n) mn = 0, V.push_back(0); else mn = min(mn, HoleDiameter(i)), V.push_back(mn); } if(id != 0) { PutLL(0, mn); PutLL(0, mx); Send(0); } else { MN[0] = mn; MX[0] = mx; for(LL i = 1; i < k; i++) { LL ii = Receive(i); MN[i] = min(MN[i - 1], GetLL(ii)); MX[i] = min(MN[i - 1], GetLL(ii)); } } mx = 0; for(LL i = s[id]; i < e[id]; i++) { if(i <= m) mx = max(mx, DiscDiameter(i)); } if(id != 0) { PutLL(0, mx); Send(0); } else { T[0] = mx; for(LL i = 1; i < k; i++) { LL ii = Receive(i); T[i] = GetLL(i); } LL in = k - 1; for(LL i = 0; i < k; i++) { if(T[i] == 0) continue; while(in >= 0 && T[i] > MX[in]) in--; if(in < 0) { if(id == 0) puts("0"); return 0; } G[in] = i + 1; in--; } for(LL i = 0; i < k; i++) { PutLL(i, G[i]); Send(i); } } LL ix = Receive(0); LL v = GetLL(ix); if(v == 0) { PutLL(0, INF); Send(0); } else { v--; LL a = 0; for(LL i = s[id + 1]; i < e[id + 1]; i++) (i <= n) ? V.push_back(min(V.back(), HoleDiameter(i))) : V.push_back(0); LL res = e[id] - 1, gg = V.size() - 1; if(id + 1 < k) res = e[id + 1] - 1; for(LL i = s[v]; i < e[v]; i++) { if(i > m) continue; a = max(DiscDiameter(i), a); if(gg < 0) gg--, res--; //printf("%lld %lld %lld %lld\n", id, gg, a, V[gg]); while(gg >= 0 && V[gg] < a) gg--, res--; } PutLL(0, res); Send(0); } if(id == 0) { for(LL i = 0; i < k; i++) { LL ii = Receive(i); ans[i] = GetLL(ii); //printf("%d %lld\n", i, ans[i]); } ans[k] = INF; LL roz = e[0] - s[0]; for(int i = k - 1; i >= 0; i--) { if(ans[i] == INF) ans[i] = ans[i + 1]; else { ans[i] = min(ans[i], ans[i + 1] - roz); } } ans[0] = max(ans[0], 0LL); printf("%lld\n", ans[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 | #include <bits/stdc++.h> #include "message.h" #include "krazki.h" using namespace std; typedef long long LL; const LL INF = 1e18 + 7; const LL N = 1007; LL n, m, k, id; LL s[N], e[N]; LL MN[N], MX[N], T[N], G[N], ans[N]; vector < LL > V; int main() { n = PipeHeight(); m = NumberOfDiscs(); k = NumberOfNodes(); id = MyNodeId(); if(m > n) { if(MyNodeId() == 0) puts("0"); return 0; } LL cp = n; while(cp % k) cp++; for(LL i = 0; i < k; i++) s[i] = i * cp / k + 1, e[i] = (i + 1) * cp / k + 1; LL mn = INF, mx; s[id] > n ? mx = 0 : mx = HoleDiameter(s[id]); //printf("%lld\n", id); //printf("%lld %lld\n", s, e); for(LL i = s[id]; i < e[id]; i++) { if(i > n) mn = 0, V.push_back(0); else mn = min(mn, HoleDiameter(i)), V.push_back(mn); } if(id != 0) { PutLL(0, mn); PutLL(0, mx); Send(0); } else { MN[0] = mn; MX[0] = mx; for(LL i = 1; i < k; i++) { LL ii = Receive(i); MN[i] = min(MN[i - 1], GetLL(ii)); MX[i] = min(MN[i - 1], GetLL(ii)); } } mx = 0; for(LL i = s[id]; i < e[id]; i++) { if(i <= m) mx = max(mx, DiscDiameter(i)); } if(id != 0) { PutLL(0, mx); Send(0); } else { T[0] = mx; for(LL i = 1; i < k; i++) { LL ii = Receive(i); T[i] = GetLL(i); } LL in = k - 1; for(LL i = 0; i < k; i++) { if(T[i] == 0) continue; while(in >= 0 && T[i] > MX[in]) in--; if(in < 0) { if(id == 0) puts("0"); return 0; } G[in] = i + 1; in--; } for(LL i = 0; i < k; i++) { PutLL(i, G[i]); Send(i); } } LL ix = Receive(0); LL v = GetLL(ix); if(v == 0) { PutLL(0, INF); Send(0); } else { v--; LL a = 0; for(LL i = s[id + 1]; i < e[id + 1]; i++) (i <= n) ? V.push_back(min(V.back(), HoleDiameter(i))) : V.push_back(0); LL res = e[id] - 1, gg = V.size() - 1; if(id + 1 < k) res = e[id + 1] - 1; for(LL i = s[v]; i < e[v]; i++) { if(i > m) continue; a = max(DiscDiameter(i), a); if(gg < 0) gg--, res--; //printf("%lld %lld %lld %lld\n", id, gg, a, V[gg]); while(gg >= 0 && V[gg] < a) gg--, res--; } PutLL(0, res); Send(0); } if(id == 0) { for(LL i = 0; i < k; i++) { LL ii = Receive(i); ans[i] = GetLL(ii); //printf("%d %lld\n", i, ans[i]); } ans[k] = INF; LL roz = e[0] - s[0]; for(int i = k - 1; i >= 0; i--) { if(ans[i] == INF) ans[i] = ans[i + 1]; else { ans[i] = min(ans[i], ans[i + 1] - roz); } } ans[0] = max(ans[0], 0LL); printf("%lld\n", ans[0]); } return 0; } |