結果
問題 | No.234 めぐるはめぐる (4) |
ユーザー |
👑 |
提出日時 | 2019-01-14 18:23:24 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 1 ms / 1,000 ms |
コード長 | 4,684 bytes |
コンパイル時間 | 2,496 ms |
コンパイル使用メモリ | 175,296 KB |
実行使用メモリ | 6,940 KB |
最終ジャッジ日時 | 2024-06-13 02:44:50 |
合計ジャッジ時間 | 3,259 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 2 |
ソースコード
import std.conv, std.stdio, std.string;import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex, std.typecons;import core.bitop;class EOFException : Throwable { this() { super("EOF"); } }string[] tokens;string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }int readInt() { return readToken().to!int; }long readLong() { return readToken().to!long; }real readReal() { return readToken().to!real; }void chmin(T)(ref T t, in T f) { if (t > f) t = f; }void chmax(T)(ref T t, in T f) { if (t < f) t = f; }int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = cast(int)(as.length); for (; low + 1 < upp; ) { int mid = (low + upp)>> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a < val)); }int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a <= val)); }immutable LIM = 12;/*./ \.---./ \ / \.---3---4 5/ \ / \ / \0 1---2---@---./ \ / \ / \ / \.---.---.---.---.*/void run() {enum LOG_BASE = 4;enum MASK = (1 << LOG_BASE) - 1;enum CLOSED = (1 << LOG_BASE) - 1;ulong encode(int[] a) {ulong ret;foreach (i; 0 .. a.length) {ret |= cast(ulong)(a[i]) << (LOG_BASE * i);}return ret;}auto ans = new BigInt[LIM + 1];BigInt[ulong] crt;crt[encode([CLOSED, CLOSED])] = 1;foreach (m; 0 .. LIM + 1) {stderr.writefln("m = %s", m);foreach (n; 0 .. m + 1) {BigInt[ulong] nxt;void add(ulong key, BigInt val) {nxt.update(key, () => val, (ref BigInt old) => old + val);}foreach (key, val; crt) {auto a = new int[m + 3];if (n == 0) {a[0] = CLOSED;foreach (i; 1 .. m + 3) {a[i] = (key >> (LOG_BASE * (i - 1))) & MASK;if (a[i] != CLOSED) {++a[i];}}} else {foreach (i; 0 .. m + 3) {a[i] = (key >> (LOG_BASE * i)) & MASK;}}debug {writefln("m = %s, n = %s, a = %s, val = %s", m, n, a, val);foreach (i; 0 .. m + 3) {if (a[i] != CLOSED) {assert(a[a[i]] == i);}}}// last rowif (m == LIM && !a[0 .. n].all!(tmp => (tmp == CLOSED))) {continue;}// skipif (a[n + 1] == CLOSED) {add(encode(a), val);}// connect 0if (a[n + 1] == CLOSED) {auto b = a.dup;b[n + 1] = n + 1;add(encode(b), val);}// connect 1foreach (y; n .. n + 3) {auto b = a.dup;if (b[y] != CLOSED) {const yy = b[y];b[yy] = n + 1;if (y != yy) {b[y] = CLOSED;}if (b[n + 1] == CLOSED) {b[n + 1] = yy;debug{// writefln(" connect 1: y = %s, b = %s",y,b);}add(encode(b), val);}}}// connect 2foreach (y0; n .. n + 3) foreach (y1; y0 + 1 .. n + 3) {auto b = a.dup;if (b[y0] != CLOSED && b[y1] != CLOSED) {if (b[y0] == y1 && b[y1] == y0) {// finishing cycleb[y0] = CLOSED;b[y1] = CLOSED;if (b.all!(tmp => (tmp == CLOSED))) {ans[m] += val;}} else {const yy0 = b[y0];const yy1 = b[y1];b[yy0] = yy1;b[yy1] = yy0;if (y0 != yy0) {b[y0] = CLOSED;}if (y1 != yy1) {b[y1] = CLOSED;}if (b[n + 1] == CLOSED) {debug{// writefln(" connect 2: y0 = %s, y1 = %s, b = %s",y0,y1,b);}add(encode(b), val);}}}}}crt = nxt;}}foreach (n; 1 .. LIM + 1) {ans[n] += ans[n - 1];}writeln(ans.to!(string[]));}void main() {// 1m17.081s// run();// return;immutable ansStr =["0", "1", "11", "110", "2402", "128967", "16767653", "5436906668", "4406952731948", "8819634719356421", "43329348004927734247","522235268182347360718818", "15436131339319739257518081878"];try {for (; ; ) {const N = readInt();writeln(ansStr[N]);}} catch (EOFException e) {}}