説明
ロボットは1から始まります1第一都市に。ロボットには3つの動作があります。その場所に留まること、次の都市の隣にいること、そして自己破壊することです。毎秒ランダムに動作をトリガーします。今すぐ絵を与え、後に尋ねるTTt秒でロボットのアクションの数はいくつですか?
1 <t≤1 0 9、1≤N≤30、0 <M <100 1 <t \ leq 10 ^ {9}、1 \ leq N \ leq 30,0 <M <100 1<t≤1 09、1≤N≤3 0 、0<M<1 0 0
解決
マップが非常に小さいため、最初に隣接行列を作成します。所定の位置に停止するには、fi、i = 1 f_ {i、i} = 1としますf私は、私=1.自己破壊の場合、仮想ノードを構築できます0 00、次にすべての点を有向エッジで接続します。つまり、fi、0 = 1 f_ {i、0} = 1f私は、0=1。
dpのプロセスを検討し、gi、j、k g_ {i、j、k}とするgI 、J 、KスレーブIIの場合私からjjjをされてしまっ株式会社k- stepプランの数、 kkを見つけることができますk次元はロールアウトできます。次に、初期状態はgi、j = fi、j g_ {i、j} = f_ {i、j}です。gI 、J=fI 、J。フロイドのアイデアを使用してに転送
fi、j = ∑ k = 1 nfi、k×fk、j f_ {i、j} = \ sum_ {k = 1} ^ n f_ {i、k} \ times f_ {k、j} fI 、J=k = 1Σn個fI 、K×fK 、J
これは行列の乗算であるため、行列はすぐに指数化されます。
時間の複雑さO(n 3 logt)O(n ^ 3 \ log t)O (n3lo gt )。
コード
マトリックス高速パワーのテンプレートを掛ける
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100 + 5, INF = 0x3f3f3f3f, mod = 1e9 + 7;
inline int read() {
int x = 0, f = 0; char ch = 0;
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
return f ? -x : x;
}
int n;
struct mat {
int m[N][N];
mat() {
memset(m, 0, sizeof(m));
for (int i = 0; i < N; i++) m[i][i] = 1;
}
};
mat mul(mat a, mat b) {
mat c;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
c.m[i][j] = 0; //Mention!
for (int k = 1; k <= n; k++)
c.m[i][j] += a.m[i][k] * b.m[k][j] % mod;
c.m[i][j] %= mod;
}
return c;
}
mat ksm(mat a, int k) {
mat res;
while (k) {
if (k & 1) res = mul(res, a);
k >>= 1;
a = mul(a, a);
}
return res;
}
signed main() {
n = read(); int k = read();
mat a;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a.m[i][j] = read();
mat ans = ksm(a, k);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
printf("%lld ", ans.m[i][j]);
puts("");
}
return 0;
}