Published 2022. 1. 27. 20:28

문제 링크

http://icpc.me/12850

 

12850번: 본대 산책2

가능한 경로의 수를 1,000,000,007로 나눈 나머지를 출력한다.

www.acmicpc.net

풀이

유배당한 불쌍한 정보대생을 위한 문제다..

분할 정복을 이용한 O(logN) 행렬 제곱을 이용하여 풀었다.

이 글을 참고하여 풀었다.

행렬 곱셈식을 곱씹어본다면 왜 이렇게 풀이할 수 있는지 알 수 있다.

 

Counting source to destination path of k length

HERE author discusses three methods to count source to destination path of k length. I am not able to get the last method which is based on divide and conquer approach and claimed to be O(V^3logk)...

stackoverflow.com

 

코드

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
#define rep(i,a,b) for(int i = a; i < b; i++)

const ll mod = 1e9 + 7;

vvl mul(const vvl &a, const vvl &b) {
    vvl ret(8, vl(8, 0));
    rep(i, 0, 8) rep(j, 0, 8) rep(k, 0, 8) {
        ret[i][j] = (ret[i][j] + (a[i][k] * b[k][j]) % mod) % mod;
    }
    return ret;
}

vvl pw(vvl a, int n) {
    vvl ret(8, vl(8, 0));
    rep(i, 0, 8) ret[i][i] = 1;
    while (n) {
        if (n % 2) ret = mul(ret, a);
        a = mul(a, a);
        n >>= 1;
    }
    return ret;
}

int main() {
    vvl a = {
        {0, 1, 0, 0, 0, 0, 0, 1},
        {1, 0, 1, 0, 0, 0, 1, 0},
        {0, 1, 0, 1, 0, 1, 1, 0},
        {0, 0, 1, 0, 1, 1, 0, 0},
        {0, 0, 0, 1, 0, 1, 0, 0},
        {0, 0, 1, 1, 1, 0, 1, 0},
        {0, 1, 1, 0, 0, 1, 0, 1},
        {1, 0, 0, 0, 0, 0, 1, 0}
    };
    int n; cin >> n;
    a = pw(a, n);
    cout << a[4][4];
}

'Algorithm > BOJ' 카테고리의 다른 글

[백준] 2481 해밍 경로  (0) 2022.02.17
[백준] 1533 길의 개수  (0) 2022.02.03
[백준] 13977 이항 계수와 쿼리  (0) 2022.01.25
[백준] 9465 스티커  (0) 2022.01.25
[백준] 15824 너 봄에는 캡사이신이 맛있단다  (0) 2022.01.25
복사했습니다!