提出 #68301791


ソースコード 拡げる

// TypeScript 5.1 / Node.js 18.16.1
// fs を用いた高速入力 + BigInt二重ハッシュによる回文判定
// 実行方法: ts-node index.ts < input.txt

import * as fs from 'fs';

/**
 * 文字列のハッシュ情報を保持する型
 */
type HashData = {
    pow: bigint[]; // base^i % mod
    hf: bigint[];  // 正方向のprefix hash (1-indexed)
    hr: bigint[];  // 逆方向のprefix hash (1-indexed)
};

/**
 * 文字列Sの前方・逆方向のハッシュ配列を構築する
 * @param S 対象文字列
 * @param base 基数 (BigInt)
 * @param mod 素数mod (BigInt)
 * @returns HashData
 */
function buildHash(S: string, base: bigint, mod: bigint): HashData {
    const n = S.length;
    const pow: bigint[] = new Array(n + 1);
    const hf: bigint[] = new Array(n + 1);
    const hr: bigint[] = new Array(n + 1);

    pow[0] = 1n;
    for (let i = 1; i <= n; i++) {
        pow[i] = (pow[i - 1] * base) % mod;
    }

    hf[0] = 0n;
    for (let i = 0; i < n; i++) {
        const val = BigInt(S.charCodeAt(i) - 96);
        hf[i + 1] = (hf[i] * base + val) % mod;
    }

    hr[0] = 0n;
    for (let i = 0; i < n; i++) {
        const val = BigInt(S.charCodeAt(n - 1 - i) - 96);
        hr[i + 1] = (hr[i] * base + val) % mod;
    }

    return { pow, hf, hr };
}

/**
 * 部分文字列のハッシュを取得(1-indexed)
 * @param hf 正方向または逆方向のハッシュ配列
 * @param pow 累乗配列
 * @param l 区間左端 (1-indexed)
 * @param r 区間右端 (1-indexed)
 * @param mod 素数mod
 * @returns 部分ハッシュ値
 */
function getSubHash(hf: bigint[], pow: bigint[], l: number, r: number, mod: bigint): bigint {
    const len = r - l + 1;
    let res = hf[r] - (hf[l - 1] * pow[len]) % mod;
    res %= mod;
    if (res < 0n) res += mod;
    return res;
}

/**
 * 回文判定クエリを処理する
 * @param N 文字列長
 * @param Q クエリ数
 * @param S 入力文字列
 * @param queries クエリ配列 [ [L, R], ... ]
 * @returns 判定結果配列 ("Yes" | "No")
 */
function solve(N: number, Q: number, S: string, queries: [number, number][]): string[] {
    // 二重ハッシュ用パラメータ
    const MOD1 = 1000000007n;
    const MOD2 = 1000000009n;
    const BASE1 = 1000003n;
    const BASE2 = 1000033n;

    // ハッシュ構築
    const h1 = buildHash(S, BASE1, MOD1);
    const h2 = buildHash(S, BASE2, MOD2);

    const res: string[] = [];

    for (let i = 0; i < Q; i++) {
        const [L, R] = queries[i];

        const fh1 = getSubHash(h1.hf, h1.pow, L, R, MOD1);
        const fh2 = getSubHash(h2.hf, h2.pow, L, R, MOD2);

        const revL = N - R + 1;
        const revR = N - L + 1;

        const rh1 = getSubHash(h1.hr, h1.pow, revL, revR, MOD1);
        const rh2 = getSubHash(h2.hr, h2.pow, revL, revR, MOD2);

        if (fh1 === rh1 && fh2 === rh2) {
            res.push("Yes");
        } else {
            res.push("No");
        }
    }
    return res;
}

// =========================
// 入力処理
// =========================
const input = fs.readFileSync(0, 'utf8').trim().split(/\s+/);
let idx = 0;
const N = Number(input[idx++]);
const Q = Number(input[idx++]);
const S = input[idx++];

const queries: [number, number][] = [];
for (let i = 0; i < Q; i++) {
    const L = Number(input[idx++]);
    const R = Number(input[idx++]);
    queries.push([L, R]);
}

// 実行 & 出力
const startTime = process.hrtime.bigint();
const result = solve(N, Q, S, queries);
const endTime = process.hrtime.bigint();

console.log(result.join('\n'));

// 処理時間・メモリ使用量(stderr出力)
console.error(`Time: ${(Number(endTime - startTime) / 1e6).toFixed(3)} ms`);
console.error(`Memory RSS: ${(process.memoryUsage().rss / 1024 / 1024).toFixed(2)} MB`);

提出情報

提出日時
問題 B56 - Palindrome Queries
ユーザ myoshizumi
言語 TypeScript 5.1 (Node.js 18.16.1)
得点 1000
コード長 3905 Byte
結果 AC
実行時間 472 ms
メモリ 127812 KiB

コンパイルエラー


			

			
				

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 1000 / 1000
結果
AC × 1
AC × 16
セット名 テストケース
Sample sample_01.txt
All killer_01.txt, killer_02.txt, killer_03.txt, max_01.txt, max_02.txt, max_03.txt, max_04.txt, max_05.txt, min_01.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, sample_01.txt
ケース名 結果 実行時間 メモリ
killer_01.txt AC 299 ms 114436 KiB
killer_02.txt AC 242 ms 112348 KiB
killer_03.txt AC 280 ms 119756 KiB
max_01.txt AC 258 ms 118244 KiB
max_02.txt AC 348 ms 117756 KiB
max_03.txt AC 326 ms 125148 KiB
max_04.txt AC 324 ms 125064 KiB
max_05.txt AC 431 ms 126988 KiB
min_01.txt AC 41 ms 42712 KiB
random_01.txt AC 469 ms 127112 KiB
random_02.txt AC 471 ms 127812 KiB
random_03.txt AC 472 ms 127544 KiB
random_04.txt AC 426 ms 127616 KiB
random_05.txt AC 432 ms 127544 KiB
random_06.txt AC 431 ms 127740 KiB
sample_01.txt AC 41 ms 42872 KiB