結果

問題 No.1855 Intersected Lines
ユーザー MitarushiMitarushi
提出日時 2022-01-05 11:06:59
言語 Nim
(2.0.2)
結果
RE  
(最新)
AC  
(最初)
実行時間 -
コード長 3,693 bytes
コンパイル時間 4,209 ms
コンパイル使用メモリ 72,412 KB
実行使用メモリ 4,504 KB
最終ジャッジ日時 2023-09-14 03:44:33
合計ジャッジ時間 5,399 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 RE -
testcase_01 RE -
testcase_02 RE -
testcase_03 RE -
testcase_04 RE -
testcase_05 RE -
testcase_06 RE -
testcase_07 RE -
testcase_08 RE -
testcase_09 RE -
testcase_10 RE -
testcase_11 RE -
testcase_12 RE -
testcase_13 RE -
testcase_14 RE -
testcase_15 RE -
testcase_16 RE -
testcase_17 RE -
testcase_18 RE -
testcase_19 RE -
testcase_20 RE -
testcase_21 RE -
testcase_22 RE -
testcase_23 RE -
testcase_24 RE -
testcase_25 RE -
testcase_26 RE -
testcase_27 RE -
testcase_28 RE -
testcase_29 RE -
testcase_30 RE -
testcase_31 RE -
testcase_32 RE -
権限があれば一括ダウンロードができます

ソースコード

diff #

import strutils, sequtils, math, sugar, algorithm

const MOD = 998244353

proc mod_pow(r, x: int): int =
    var
        r = r
        x = x
    result = 1
    while x > 0:
        if x mod 2 == 1:
            result = result * r mod MOD
        r = r * r mod MOD
        x = x div 2

type Combination = ref object
    factorial: seq[int]
    factorial_inv: seq[int]

proc init_combination(n: int): Combination =
    result = Combination(
        factorial: newSeq[int](n),
        factorial_inv: newSeq[int](n)
    )

    result.factorial[0] = 1
    for i in 1..<n:
        result.factorial[i] = result.factorial[i - 1] * i mod MOD
    result.factorial_inv[n - 1] = mod_pow(result.factorial[n - 1], MOD - 2)
    for i in countdown(n - 1, 1):
        result.factorial_inv[i - 1] = result.factorial_inv[i] * i mod MOD

proc combination(c: Combination, a, b: int): int =
    if a < 0 or b < 0 or a < b:
        return 0

    c.factorial[a] * c.factorial_inv[b] mod MOD * c.factorial_inv[a - b] mod MOD

proc fft(a: var seq[int], w: seq[int]) =
    let n = a.len
    var
        m = n
        t = 1
    while m >= 2:
        let mh = m shr 1
        for i in countup(0, n-1, m):
            for s in 0..<mh:
                let
                    j = i + s
                    k = j + mh
                (a[j], a[k]) = ((a[j] + a[k]) mod MOD, (a[j] - a[k]) * w[s * t] mod MOD)
        m = mh
        t *= 2

proc ifft(a: var seq[int], w: seq[int]) =
    let n = a.len
    var
        m = 2
        t = n shr 1
    while m <= n:
        let mh = m shr 1
        for i in countup(0, n-1, m):
            for s in 0..<mh:
                let
                    j = i + s
                    k = j + mh
                a[k] *= w[n - s * t]
                (a[j], a[k]) = ((a[j] + a[k]) mod MOD, (a[j] - a[k]) mod MOD)
        m = m shl 1
        t = t shr 1

    let n_inv = mod_pow(n, MOD - 2)
    for i in 0..<n:
        a[i] *= n_inv
        a[i] = a[i] mod MOD

proc convolution(a, b: seq[int]): seq[int] =
    let n2 = max(a.len + b.len - 1, 1)
    let n = n2.nextPowerOfTwo
    var
        a = a
        b = b
    a.setLen(n)
    b.setLen(n)

    let w_root = mod_pow(3, (MOD - 1) div n)
    var w = newSeq[int](n + 1)
    w[0] = 1
    for i in 1..n:
        w[i] = w[i - 1] * w_root mod MOD

    fft(a, w)
    fft(b, w)

    result = collect(newSeq):
        for (x, y) in zip(a, b):
            x * y mod MOD

    ifft(result, w)
    result.setLen(n2)

    for idx, i in result:
        if i < 0:
            result[idx] += MOD

proc inv(x: int): int =
    mod_pow(x, MOD - 2)

proc double_factorial(c: Combination, x: int): int =
    c.factorial[x] * c.factorial_inv[x div 2] mod MOD * mod_pow(2, MOD - 1 - x div 2) mod MOD

let n = stdin.readLine.parseInt
let s = stdin.readLine

let 
    r = s.count('R')
    b = s.count('B')

if r mod 2 == 1 or b mod 2 == 1:
    echo 0
    quit()

let c = init_combination(500000)

var ans = 0

if r >= 4:
    ans += combination(c, r, 4) * double_factorial(c, r - 4) mod MOD * double_factorial(c, b)
    ans = ans mod MOD

if b >= 4:
    ans += combination(c, b, 4) * double_factorial(c, b - 4) mod MOD * double_factorial(c, r)
    ans = ans mod MOD

if r >= 2 and b >= 2:
    var acc = newSeq[int](2 * n)
    var acc_b = 0
    for i in s:
        if i == 'B':
            acc_b += 1
        else:
            acc[acc_b] += 1
    
    var acc_rev = acc
    acc_rev.reverse()
    let conv = convolution(acc, acc_rev)

    var sum = 0
    for i in 0..<2*n:
        sum += conv[i + 2 * n - 1] * i mod MOD * (b - i)
        sum = sum mod MOD

    ans += sum * double_factorial(c, r - 2) mod MOD * double_factorial(c, b - 2)
    ans = ans mod MOD

echo ans
0