結果

問題 No.1073 無限すごろく
ユーザー semisagisemisagi
提出日時 2020-06-05 22:34:51
言語 Swift
(5.10.0)
結果
AC  
実行時間 3 ms / 2,000 ms
コード長 3,120 bytes
コンパイル時間 3,221 ms
コンパイル使用メモリ 133,064 KB
実行使用メモリ 7,964 KB
最終ジャッジ日時 2023-08-20 15:26:39
合計ジャッジ時間 5,044 ms
ジャッジサーバーID
(参考情報)
judge12 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
7,764 KB
testcase_01 AC 3 ms
7,844 KB
testcase_02 AC 2 ms
7,764 KB
testcase_03 AC 2 ms
7,760 KB
testcase_04 AC 3 ms
7,728 KB
testcase_05 AC 3 ms
7,852 KB
testcase_06 AC 3 ms
7,784 KB
testcase_07 AC 2 ms
7,748 KB
testcase_08 AC 3 ms
7,820 KB
testcase_09 AC 2 ms
7,768 KB
testcase_10 AC 3 ms
7,760 KB
testcase_11 AC 3 ms
7,748 KB
testcase_12 AC 2 ms
7,768 KB
testcase_13 AC 2 ms
7,792 KB
testcase_14 AC 3 ms
7,964 KB
testcase_15 AC 2 ms
7,732 KB
testcase_16 AC 3 ms
7,824 KB
testcase_17 AC 2 ms
7,872 KB
testcase_18 AC 3 ms
7,764 KB
testcase_19 AC 3 ms
7,764 KB
testcase_20 AC 2 ms
7,724 KB
testcase_21 AC 3 ms
7,820 KB
testcase_22 AC 2 ms
7,792 KB
testcase_23 AC 2 ms
7,724 KB
testcase_24 AC 2 ms
7,792 KB
testcase_25 AC 3 ms
7,788 KB
testcase_26 AC 2 ms
7,788 KB
testcase_27 AC 3 ms
7,832 KB
testcase_28 AC 3 ms
7,672 KB
testcase_29 AC 2 ms
7,664 KB
testcase_30 AC 2 ms
7,716 KB
testcase_31 AC 2 ms
7,648 KB
testcase_32 AC 3 ms
7,832 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

class Scanner {
    private var stack = [String]()
    private var index = 0
    
    func peek() -> String {
        if stack.count == index {
            stack += readLine()!.split(separator: " ").map{ String($0) }
        }
        return stack[index]
    }
    
    func next() -> String {
        let value = peek()
        index += 1
        return value
    }
    
    func nextInt() -> Int {
        return Int(next())!
    }
    
    func nextDouble() -> Double {
        return Double(next())!
    }
}

extension String {
    var characters: [Character] {
        self.map{ $0 }
    }
}

let mod = 1000000007

struct Modulo {
    let n: Int
    
    init(_ n: Int) {
        self.n = n
    }
    
    static func +(lhs: Self, rhs: Self) -> Self {
        return Modulo((lhs.n + rhs.n) % mod)
    }
    
    static func -(lhs: Self, rhs: Self) -> Self {
        return Modulo((lhs.n + mod - rhs.n) % mod)
    }
    
    static func *(lhs: Self, rhs: Self) -> Self {
        return Modulo((lhs.n * rhs.n) % mod)
    }
    
    static func +=(lhs: inout Self, rhs: Self) {
        lhs = lhs + rhs
    }
    
    static func -=(lhs: inout Self, rhs: Self) {
        lhs = lhs - rhs
    }
    
    static func *=(lhs: inout Self, rhs: Self) {
        lhs = lhs * rhs
    }
    
    func inverse() -> Self {
        // x * self = 1 (mod P) となるxを求める。
        // exists y, x * self - 1 = P*yと同値。
        // x*self - P*y = 1
        var x1 = 1, y1 = 0, z1 = n
        var x2 = 0, y2 = 1, z2 = -mod
        while z2 != 0 {
            let q = z1 / z2
            x1 -= x2 * q
            y1 -= y2 * q
            z1 -= z2 * q
            swap(&x1, &x2)
            swap(&y1, &y2)
            swap(&z1, &z2)
        }
        x1 %= mod
        if x1 < 0 {
            x1 += mod
        }
        return Modulo(x1)
    }
}

let sixth = Modulo(6).inverse()

struct Polynomial {
    let a: [Modulo]
    
    init(_ a: [Modulo]) {
        self.a = a
    }
    
    init(_ a: [Int]) {
        self.a = a.map(Modulo.init)
    }
    
    static var zero: Polynomial {
        get {
            Polynomial([0, 0, 0, 0, 0, 0])
        }
    }
    
    static var one: Polynomial {
        get {
            Polynomial([1, 0, 0, 0, 0, 0])
        }
    }
    
    subscript(index: Int) -> Modulo {
        a[index]
    }
    
    static func *(lhs: Self, rhs: Self) -> Self {
        var c = Array.init(repeating: Modulo(0), count: 11)
        for i in 0 ... 5 {
            for j in 0 ... 5 {
                c[i + j] += lhs[i] * rhs[j]
            }
        }
        for i in (6 ... 10).reversed() {
            for j in 0 ... 5 {
                c[i - 6 + j] += c[i] * sixth
            }
        }
        return Polynomial(Array(c[0 ... 5]))
    }
    
    func power(_ n: Int) -> Polynomial {
        if n == 0 { return .one }
        let value = power(n / 2)
        if n % 2 == 0 {
            return value * value
        } else {
            return value * value * self
        }
    }
}

var scanner = Scanner()
let N = scanner.nextInt()
print(Polynomial([0, 1, 0, 0, 0, 0]).power(N + 5)[5].n)

0