내용으로 건너뛰기
테페리넷
사용자 도구
등록
로그인
사이트 도구
검색
도구
문서 보기
Fold/unfold all
역링크
미디어 관리자
사이트맵
등록
로그인
>
미디어 관리자
사이트맵
현재 위치:
테페리넷
»
Problem Solving
»
문제
»
백준 온라인 저지 (BOJ)
»
행렬 제곱
ps:problems:boj:10830
이 문서는 읽기 전용입니다. 원본을 볼 수는 있지만 바꿀 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하세요.
====== 행렬 제곱 ====== ===== 풀이 ===== * [[ps:거듭제곱의 빠른 계산]] 을 행렬에 적용하는 문제. * n*n 행렬의 곱셈은 O(n^3)이고, 빠른 계산 알고리즘을 이용하면 행렬 곱셈을 O(logb)번만 하면 되므로 총 시간 복잡도는 O(n^3logb) * 정수의 n제곱을 계산하는 [[ps:problems:boj:1629]] 문제는 그냥 python의 내장 pow 함수로 가능했지만, 행렬은 알고리즘을 직접 구현해야 한다. 사실 행렬 거듭제곱의 빠른 계산은 [[ps:선형 점화식#상수계수의 선형 점화식 (동차 선형 점화식)|동차 선형 점화식]]의 계산에 필요하기 때문에 [[ps:teflib:combinatorics#linear_homogeneous_recurrence|teflib.combinatorics.linear_homogeneous_recurrence]]의 일부로 이미 구현되어있다. 여기에서 행렬 거듭제곱 부분만 복사해서 제출했다. ===== 코드 ===== <dkpr py> """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() </dkpr> {{tag>BOJ ps:problems:boj:골드_4}}
ps/problems/boj/10830.txt
· 마지막으로 수정됨: 2021/07/28 16:03 저자
teferi
문서 도구
문서 보기
역링크
Fold/unfold all
맨 위로