BOJ 13728 행렬식과 GCD
알고리즘 문제풀이/BOJ 2020. 1. 20. 04:00난이도 : Solved.ac 기준 Platinum 4
1. 문제 설명
다음과 같은 형태의 n×n 행렬
Mn=(Mij)={1i=j1j=i+1−1j=i−1 즉, 예를 들어 n=4 인 경우 (1100−11100−11100−11) 이런 형태가 되게 된다. 이때, 다음 값을 계산하는 문제.
n∑i=1gcd(detMi,detMn)
2. 풀이
먼저, 위 규칙대로 생성된 n×n 행렬의 행렬식의 수열을 di 라고 하자.
이때, d1=1,d2=2 는 직접 계산해서 찾을 수 있다.
dk 를 구하기 위해, 행렬식을 첫 행을 기준으로 직접 계산 (Cofactor Expansion) 하는 과정을 써 보면,
첫 행에서 0이 아닌 entry는 첫 두 개 뿐이며, 그중 첫 열을 기준으로 전개하면 dk−1 을 얻는다.
두 번째 열을 기준으로 전개하면, 다음과 같은 행렬의 determinant를 계산할 필요가 있음을 알게 된다.
(−110011011)
이때, 이 새로운 행렬도 다시 여인수 전개해 보면 첫 열에 대해서는 −dk−2 를 얻고, 두 번째 열에 대해서는 rank가 k−2 보다 작으므로 0이 된다. 따라서, 이를 이용하면
dk=dk−1+dk−2 를 얻으며, 이 식은 피보나치 수열 형태임을 바로 알 수 있다.
또한, 피보나치 수열 fi 에 대해, gcd(fi,fj)=fgcd(i,j) 임이 잘 알려져 있다.
3. 코드
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define mod 1000000007
int fibo[101010] = {0,1};
int32_t main()
{
int ans = 0;
int n; cin >> n;
for (int i = 2; i<=101000; i++)
fibo[i] = (fibo[i-1]+fibo[i-2])%mod;
for (int i = 1; i<=n; i++)
{
ans += (fibo[__gcd(i+1,n+1)]);
ans %= mod;
}
cout << ans%mod << '\n';
}
'알고리즘 문제풀이 > BOJ' 카테고리의 다른 글
BOJ 12728 n제곱 계산 / 12925 Numbers (2) | 2020.01.30 |
---|---|
BOJ 15745 Snow Boots (0) | 2020.01.23 |
BOJ 17840 피보나치 음악 (0) | 2020.01.09 |
BOJ 1557 제곱 ㄴㄴ / BOJ 8464 Non-Squarefree Numbers (2) | 2020.01.04 |
BOJ 2465 줄 세우기 (0) | 2019.10.31 |