[HNOI2008]GT考试
題意
有一個長度為\(n\)\((n\le1e^9)\)只由阿拉伯數字組成的串\(A\),現在給一個長度為\(m\)\((m\le20)\)同樣只由阿拉伯數字組成的串\(B\),求滿足條件的\(A\)串個數,條件:\(B\)串不包含在\(A\)串。
題解
\(dp[i][j]=\)長度為\(i\)且末尾(后綴)已經與\(B\)串首部(前綴)匹配了\(j\)位的滿足條件的串的方案數。則:\[dp[i][j] = \sum_{k = 0}^{m - 1}dp[i - 1][k]*a[k][j]\] \(a[k][j]=\) 已經匹配了\(k\)位現在再加一個數字而能匹配\(j\)位的方案數。比如\(B\)串為\(12315\),\(a[1][1] = 1\)就是\(1 + ?\)能與\(12315\)匹配\(1\)位的方案數是1的\(?\)的取值個數(\(? = 1\))。這里講的匹配是指\(1?\)的后綴與\(12315\)的前綴相同的串的長度。\[a = \begin{pmatrix} 9 & 1 & 0 & 0 & 0 & 0 \\ 8 & 1 & 1 & 0 & 0 & 0 \\ 8 & 1 & 0 & 1 & 0 & 0 \\ 9 & 0 & 0 & 0 & 1 & 0 \\ 7 & 1 & 1 & 0 & 0 & 1 \end{pmatrix}\]行代表\(k\),列代表\(j\)。如何求出\(a\)數組?既然是在求公共的前綴和后綴,故聯想到\(KMP\)的\(Next\)數組。具體做法見代碼。觀察上面的轉移方程,系數都是常數且是一次方程,自然而然的轉化為矩陣的乘積形式,以\(m\) = 5,\(B\)串為:12315為例\[\begin{pmatrix} dp[i][0] & \dots & dp[i][m - 1] \end{pmatrix}= \begin{pmatrix} dp[i - 1][0] & \dots & dp[i - 1][m - 1] \end{pmatrix}* \begin{pmatrix} 9 & 1 & 0 & 0 & 0 \\ 8 & 1 & 1 & 0 & 0 \\ 8 & 1 & 0 & 1 & 0 \\ 9 & 0 & 0 & 0 & 1 \\ 7 & 1 & 1 & 0 & 0 \end{pmatrix}\]因為是求不包含\(B\)串的A串個數,故\(a\)矩陣的最后一列應該忽略。
const int N = 100005;int mod;struct mat {int t;int A[22][22];mat() {mem(A, 0);}void Inite(int m) {t = m;}mat operator * (const mat& tp) {mat ans;ans.t = tp.t;rep(i, 0, t) rep(j, 0, t) rep(k, 0, t) {ans.A[i][j] += A[i][k] * tp.A[k][j];ans.A[i][j] %= mod;}return ans;}void operator = (const mat& tp) {t = tp.t;rep(i, 0, t) rep(j, 0, t) A[i][j] = tp.A[i][j];} };int n, m; int nxt[22];string s;mat qpow(mat C, int x) {mat B;B.Inite(m);rep(i, 0, m) B.A[i][i] = 1;for (; x; C = C * C, x >>= 1) if (x & 1) B = B * C;return B; }void Next(){nxt[0] = nxt[1] = 0;rep(i, 1, m) {int k = nxt[i];while(k && s[k] != s[i]) k = nxt[k];nxt[i + 1] = (s[k] == s[i] ? k + 1 : 0);} }int main() {cin >> n >> m >> mod >> s;Next();mat B;B.Inite(m);rep(i, 0, m) for (char j = '0'; j <= '9'; ++j) {int k = i;while(k && s[k] != j) k = nxt[k];if (s[k] == j) k++;if (k != m) B.A[i][k]++;}mat C = qpow(B, n);mat D;D.Inite(m);D.A[0][0] = 1;C = D * C;int ans = 0;rep(i, 0, m) ans = (ans + C.A[0][i]) % mod;cout << ans << endl;return 0; } 轉載于:https://www.cnblogs.com/zgglj-com/p/9729284.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的[HNOI2008]GT考试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 下载历史版本的 xCode
- 下一篇: 关于实现Runnable接口的类中有公共