Codeforces 222 E. Decoding Genome
問題
m個のアルファベットからなる長さnのDNAの総数を求めよ。
ただし禁止パターンがk個あり、
禁止パターンは2文字の連続するアルファベットにより指定される。
(この順にアルファベットが出るDNAはだめだが、逆順に出るものはOK)
制約条件
n≦10^15
m≦52
k≦m * m
方針
行列の累乗するだけ。
ソースコード
const int mod = 1000000007; typedef vector<vi> M; M operator*(M &a, M &b){ M c(a.size(), vi(b[0].size())); rep(i, c.size()) rep(j, c[0].size()){ rep(k, b.size()){ c[i][j] += (ll)a[i][k] * b[k][j] % mod; c[i][j] %= mod; } } return c; } M pow(M m, ll n){ M res(m.size(), vi(m[0].size())); rep(i, m.size()) res[i][i] = 1; for(; n; n /= 2){ if(n & 1) res = res * m; m = m * m; } return res; } int to(char c){ if(islower(c)) return c - 'a'; return c - 'A' + 26; } int main(){ ll n, m, k; cin >> n >> m >> k; M ma(m, vi(m, 1)); rep(i, k){ string s; cin >> s; ma[to(s[0])][to(s[1])] = 0; } M x(m, vi(1, 1)); ma = pow(ma, n - 1); x = ma * x; ll ans = 0; rep(i, m) ans += x[i][0]; cout << ans % mod << endl; return 0; }