結果
問題 |
No.3047 Verification of Sorting Network
|
ユーザー |
👑 |
提出日時 | 2025-02-12 19:45:29 |
言語 | TypeScript (5.7.2) |
結果 |
AC
|
実行時間 | 848 ms / 2,000 ms |
コード長 | 4,261 bytes |
コンパイル時間 | 8,240 ms |
コンパイル使用メモリ | 266,704 KB |
実行使用メモリ | 59,676 KB |
最終ジャッジ日時 | 2025-03-05 20:41:00 |
合計ジャッジ時間 | 47,817 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 61 |
ソースコード
{ const MaxT: number = 1000; 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[]> { // initial state: all elements are unknown const stack: [number, number, number][] = [ [(1 << n) - 1, (1 << n) - 1, 0], ]; const unused: boolean[] = Array(cmps.length).fill(true); let unsorted_i = 0; const m = cmps.length; // branch loop a: while (stack.length > 0) { // get branch state // z: 0 bitwise state // o: 1 bitwise states // i: index of cmps let [z, o, i] = stack.pop()!; // CEs (compare/exchange elements) loop while (i < m) { // get next comparison let [a, b] = cmps[i++]; if (((o >> a) & 1) == 0 || ((z >> b) & 1) == 0) { // (0, 0) or (1, 1) or (0, 1) or (0, ?) or (?, 1), no operation, continue to next CE } else if (((z >> a) & 1) == 1 && ((o >> b) & 1) == 1) { unused[i - 1] = false; // both elements are unknown // branch into (0, 0) and (?, 1) // copy state for (0, 0) new branch // set state for (?, 1) current branch let qz = z; let qo = (o ^ (1 << a) ^ (1 << b)); z ^= (1 << b); // if 'qz,qo' not sorted, push branch into stack if ((qo & (qz >> 1)) != 0) { stack.push([qz, qo, i]); } // z,o is sorted, continue to next branch if ((o & (z >> 1)) == 0) { continue a; } } else { unused[i - 1] = false; // if (1, 0) or (?, 0) or (1, ?), swap elements let xz = (((z >> a) ^ (z >> b)) & 1); let xo = (((o >> a) ^ (o >> b)) & 1); z ^= ((xz << a) | (xz << b)); o ^= ((xo << a) | (xo << b)); // z,o is sorted, continue to next branch if ((o & (z >> 1)) == 0) { continue a; } } } // if z,o is not sorted unsorted_i |= (o & (z >> 1)); } if (unsorted_i != 0) { const unsorted: boolean[] = Array.from({ length: n - 1 }, (_, i) => ((unsorted_i >> i) & 1) != 0); return Err(unsorted); } // if p is sorted for all branches 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); if (cost > MaxCost) throw new Error(`Cost must be <= ${MaxCost}`); // 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(" ") ); } } } main(); }