https://www.acmicpc.net/problem/12850
- 문제의 노드간의 인접행렬을 표현하면 map[a][b]는 a->b로 가는 경우의 수 이다.
- 바로 위의 인접행렬 2개를 곱하면(인접행렬곱) map2[a][b]는 a->b로 가되 시간이 2가 걸리는 경우의 수이다.
- 바로 위의 인접행렬 2개를 곱하면(인접행렬곱) map3[a][b]는 a->b로 가되 시간이 4가 걸리는 경우의 수이다.
- ....
- adj[0][a][b] : 시간이 2^0걸리며 a->b로 가는 경우의 수
- adj[1][a][b] : 시간이 2^1걸리며 a->b로 가는 경우의 수
- adj[2][a][b] : 시간이 2^2걸리며 a->b로 가는 경우의 수
- ...
import java.io.*;
import java.util.*;
class Main {
public static BufferedReader br;
public static BufferedWriter bw;
public static int N, MAX_EXP, MOD = 1000000007;
public static int[][][] map;
public static int solve() {
// N을 이진법으로 표현
int cur = N;
int exp = 0;
int remain = 0;
int[][] tmp, tmp2;
tmp = new int[8][8];
tmp2 = new int[8][8];
boolean init = false;
while (true) {
if (cur == 0) break;
remain = cur % 2;
cur = cur / 2;
if (remain == 1) {
//임시 배열 초기화
if (!init) {
init = true;
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
tmp[i][j] = map[exp][i][j];
}
//이전 배열과 행렬곱
else {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
long sum = 0;
for (int k = 0; k < 8; k++)
sum = (sum + (long)tmp[i][k] * (long)map[exp][k][j]) % MOD;
tmp2[i][j] = (int)sum;
}
}
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
tmp[i][j] = tmp2[i][j];
}
}
exp++;
}
return tmp[0][0];
}
public static void input() throws IOException {
bw = new BufferedWriter(new OutputStreamWriter(System.out));
br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
//인접행렬 크기 구하기
int cur = N;
MAX_EXP = 0;
while(true) {
if (cur == 1) break;
MAX_EXP++;
cur /= 2;
}
//인접행렬 초기화
map = new int[MAX_EXP + 1][8][8];
map[0] = new int[][]{
{0,1,1,0,0,0,0,0},
{1,0,1,1,0,0,0,0},
{1,1,0,1,1,0,0,0},
{0,1,1,0,1,1,0,0},
{0,0,1,1,0,1,1,0},
{0,0,0,1,1,0,0,1},
{0,0,0,0,1,0,0,1},
{0,0,0,0,0,1,1,0}
};
for (int i = 1; i < MAX_EXP + 1; i++) {
for (int a = 0; a < 8; a++) {
for (int b = 0; b < 8; b++) {
long sum = 0;
for (int c = 0; c < 8; c++)
sum = (sum + (long)map[i-1][a][c] * (long)map[i-1][c][b]) % MOD;
map[i][a][b] = (int)sum;
}
}
}
}
public static void main(String[] args) throws IOException {
input();
bw.write(solve() + "\n");
bw.flush();
}
}