結果
問題 |
No.3047 Verification of Sorting Network
|
ユーザー |
👑 |
提出日時 | 2025-02-10 18:34:41 |
言語 | TypeScript (5.7.2) |
結果 |
AC
|
実行時間 | 1,285 ms / 2,000 ms |
コード長 | 3,422 bytes |
コンパイル時間 | 8,610 ms |
コンパイル使用メモリ | 269,676 KB |
実行使用メモリ | 72,380 KB |
最終ジャッジ日時 | 2025-03-05 20:39:58 |
合計ジャッジ時間 | 68,429 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 61 |
ソースコード
{ const MaxT: number = 10000; const MaxN: number = 27; const MaxCost: number = 1e8; type Result<Success, Error> = Ok<Success> | Err<Error>; type Ok<Success> = { tag: "Yes"; data: Success }; type Err<Error> = { tag: "No"; data: Error }; const Ok = <Success>(data: Success): Ok<Success> => ({ tag: "Yes", data }); const Err = <Error>(data: Error): Err<Error> => ({ tag: "No", data }); function isSortingNetwork( n: number, cmps: [number, number][] ): Result<boolean[], boolean[]> { const m = cmps.length; const unused: boolean[] = Array(m).fill(true); const unsorted: boolean[] = Array(n - 1).fill(false); const bi_n = BigInt(n); const pbits = 16; const bi_pbits = BigInt(pbits); const bi_pfull = (1n << (1n << bi_pbits)) - 1n; const lows = Array(bi_pbits); for (let i = 0n; i < bi_pbits; i += 1n) { let le = ((1n << (1n << i)) - 1n) << (1n << i); for (let j = i + 1n; j < bi_pbits; j += 1n) { le |= (le << (1n << j)); } lows[Number(i)] = le; } const limit = bi_n >= bi_pbits ? (1n << (bi_n - bi_pbits)) : 1n; for (let i = 0n; i < limit; i += 1n) { let p = Array.from({ length: n }, (_, j) => j < pbits ? lows[j] : ((i >> BigInt(j - pbits)) & 1n) == 1n ? bi_pfull : 0n); for (let j = 0; j < m; ++j) { let [a, b] = cmps[j]; let na = p[a] & p[b]; if (p[a] != na) { p[b] = p[a] | p[b]; p[a] = na; unused[j] = false; } } for (let j = 0; j < n - 1; ++j) { if ((p[j] & ~p[j + 1]) != 0n) { unsorted[j] = true; } } } if (unsorted.some((x) => x)) { return Err(unsorted); } return Ok(unused); } function main(): void { const input: string[] = require("fs") .readFileSync("/dev/stdin", "utf8") .split("\n"); let index = 0; const t = parseInt(input[index++], 10); if (t > MaxT) throw new Error(`t must be <= ${MaxT}`); // phi = (1 + sqrt(5)) / 2 : golden ratio const phi = Math.sqrt(1.25) + 0.5; // testcases cost <= 1e8 let cost = 0.0; for (let i = 0; i < t; ++i) { const [n, m] = input[index++].split(" ").map((str) => parseInt(str, 10)); if (!(2 <= n && n <= MaxN && 1 <= m && m <= (n * (n - 1)) / 2)) throw new Error("Invalid n or m"); cost += m * Math.pow(phi, n); // 1-indexed to 0-indexed const va: number[] = input[index++].split(" ").map((str) => parseInt(str, 10) - 1); const vb: number[] = input[index++].split(" ").map((str) => parseInt(str, 10) - 1); const cmps: [number, number][] = va.map((a, i) => [a, vb[i]]); if (cmps.length !== m) throw new Error("Invalid cmps length"); if (cmps.some(([a, b]) => !(0 <= a && a < b && b < n))) throw new Error("Invalid a or b"); const { data, tag } = isSortingNetwork(n, cmps); console.log(tag); if (tag === "Yes") { if (data.length !== m) throw new Error("Invalid data length"); console.log(data.filter((x) => x).length); console.log( data .map((x, i) => (x ? i + 1 : 0)) .filter((x) => x) .join(" ") ); } else if (tag === "No") { if (data.length !== n - 1) throw new Error("Invalid data length"); console.log(data.filter((x) => x).length); console.log( data .map((x, i) => (x ? i + 1 : 0)) .filter((x) => x) .join(" ") ); } } if (cost > MaxCost) throw new Error(`Cost must be <= ${MaxCost}`); } main(); }