목차

행렬 제곱

ps
링크acmicpc.net/…
출처BOJ
문제 번호10830
문제명행렬 제곱
레벨골드 4
분류

거듭제곱의 빠른 계산

시간복잡도O(n^3logb)
인풋사이즈n<=5, b<=100,000,000,000
사용한 언어Python
제출기록29200KB / 80ms
해결날짜2021/07/28

풀이

코드

"""Solution code for "BOJ 10830. 행렬 제곱".

- Problem link: https://www.acmicpc.net/problem/10830
- Solution link: http://www.teferi.net/ps/problems/boj/10830

Tags: [BinaryExponentiation]
"""

MOD = 1000


class SqMat(object):
    """A very simple implementation for n x n matrix."""

    def __init__(self, mat):
        self._mat = mat

    def __getitem__(self, row):
        return self._mat[row]

    def __matmul__(self, other):
        ret = []
        for a_row in self._mat:
            ret.append([sum(a * b for a, b in zip(a_row, b_col)) 
                        for b_col in zip(*other._mat)])
        return SqMat(ret)

    def __mod__(self, mod):
        return SqMat([[item % mod for item in row] for row in self._mat])

    def __pow__(self, n, mod=0):
        res = SqMat([[0] * len(self._mat) for _ in self._mat])
        for i, row in enumerate(res):
            row[i] = 1
        m = SqMat([row[:] for row in self._mat])
        while n:
            if n % 2 == 1:
                res @= m
            m @= m
            if mod > 0:
                m %= mod
            n //= 2
        return res % mod if mod > 0 else res
    
    
def main():
    N, B = [int(x) for x in input().split()]
    mat = [[int(x) for x in input().split()] for _ in range(N)]
    
    answer = pow(SqMat(mat), B, MOD)
    
    for row in answer:
        print(*row)


if __name__ == '__main__':
    main()