結果
| 問題 |
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();
}