# 수학
우선 수가 크기 때문에 dp로도 안풀린다.
-> logn으로 해결해야한다.
수학 행렬을 사용하면 된다.
이 문제를 풀기 전에 피보나치수3을 푸는것을 추천한다.
https://www.acmicpc.net/problem/2749
피보나치 수은 이전의 2개를 더한다면
이번 문제에서는 이전의 d개의 수를 더해주면 된다.
여기서 기존의 d=2 기존의 피보나치의 수와 같은 행렬의 제곱으로 해결할 수 있고
d>2의 경우, 다음과 같이 해결이 된다.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define MAX 1005
#define INF 987654321
#define MOD 31991
#pragma warning(disable:4996)
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
int d,t;
struct st
{
int m[55][55] = {};
st operator*(st a) const
{
st ret;
for (int i = 0; i < d; i++)
for (int j = 0; j < d; j++)
for (int k = 0; k < d; k++)
ret.m[i][j] = (ret.m[i][j] + m[i][k] * a.m[k][j]) % MOD;
return ret;
}
}ans,ori,b;
int main()
{
scanf("%d%d",&d,&t);
for(int i=0;i<d;i++)
{
ans.m[i][i]=ori.m[0][i]=1;
if(0<i)
ori.m[i][i-1]=1;
}
while(t>0)
{
if(t%2==1)
ans=ans*ori;
ori=ori*ori;
t/=2;
}
printf("%d",ans.m[0][0]);
return 0;
}'IT > BOJ' 카테고리의 다른 글
| 백준(BOJ) 13333 Q-인덱스 * (0) | 2018.08.17 |
|---|---|
| 백준(BOJ) 11068 회문인 숫자 * (0) | 2018.08.16 |
| 백준(BOJ) 14753 MultiMax (0) | 2018.08.10 |
| 백준(BOJ) 13325 이진트리 * (0) | 2018.08.10 |
| 백준(BOJ) 14754 pizza boxes * (0) | 2018.08.08 |