#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; } |
English