89 lines
1.6 KiB
Plaintext
89 lines
1.6 KiB
Plaintext
Program Paraffins;
|
|
|
|
uses
|
|
gmp;
|
|
|
|
const
|
|
max_n = 500;
|
|
branch = 4;
|
|
|
|
var
|
|
rooted, unrooted: array [0 .. max_n-1] of mpz_t;
|
|
c: array [0 .. branch-1] of mpz_t;
|
|
cnt, tmp: mpz_t;
|
|
n: integer;
|
|
fmt: pchar;
|
|
sum: integer;
|
|
|
|
procedure tree(br, n, l: integer; sum: integer; cnt: mpz_t);
|
|
var
|
|
b, m: integer;
|
|
begin
|
|
for b := br + 1 to branch do
|
|
begin
|
|
sum := sum + n;
|
|
if sum >= max_n then
|
|
exit;
|
|
|
|
(* prevent unneeded long math *)
|
|
if (l * 2 >= sum) and (b >= branch) then
|
|
exit;
|
|
|
|
if b = (br + 1) then
|
|
mpz_mul(c[br], rooted[n], cnt)
|
|
else
|
|
begin
|
|
mpz_add_ui(tmp, rooted[n], b - br - 1);
|
|
mpz_mul(c[br], c[br], tmp);
|
|
mpz_divexact_ui(c[br], c[br], b - br);
|
|
end;
|
|
|
|
if l * 2 < sum then
|
|
mpz_add(unrooted[sum], unrooted[sum], c[br]);
|
|
|
|
if b < branch then
|
|
begin
|
|
mpz_add(rooted[sum], rooted[sum], c[br]);
|
|
for m := n-1 downto 1 do
|
|
tree(b, m, l, sum, c[br]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure bicenter(s: integer);
|
|
begin
|
|
if odd(s) then
|
|
exit;
|
|
mpz_add_ui(tmp, rooted[s div 2], 1);
|
|
mpz_mul(tmp, rooted[s div 2], tmp);
|
|
mpz_tdiv_q_2exp(tmp, tmp, 1);
|
|
|
|
mpz_add(unrooted[s], unrooted[s], tmp);
|
|
end;
|
|
|
|
begin
|
|
for n := 0 to 1 do
|
|
begin
|
|
mpz_init_set_ui(rooted[n], 1);
|
|
mpz_init_set_ui(unrooted[n], 1);
|
|
end;
|
|
for n := 2 to max_n-1 do
|
|
begin
|
|
mpz_init_set_ui(rooted[n], 0);
|
|
mpz_init_set_ui(unrooted[n], 0);
|
|
end;
|
|
for n := 0 to BRANCH-1 do
|
|
mpz_init(c[n]);
|
|
|
|
mpz_init(tmp);
|
|
|
|
mpz_init_set_ui(cnt, 1);
|
|
sum := 1;
|
|
for n := 1 to MAX_N do
|
|
begin
|
|
tree(0, n, n, sum, cnt);
|
|
bicenter(n);
|
|
mp_printf('%d: %Zd'+chr(13)+chr(10), n, @unrooted[n]);
|
|
end;
|
|
end.
|