行列の乗算---------- GTテスト

GTのテストを登録する準備ができてああセン、チケット番号はNNです

数字X1X2⋯⋯XnX1X2 Xnを

彼は、チケット番号の不吉な数の表示されたくありません。彼の不運な数字A1A2⋯⋯AmA1A2アム

そこミリメートル

ビット、X1X2⋯⋯XnX1X2 Xnのを指し、表示されません。

A1A2⋯⋯AmA1A2アムに等しい期間中だけではなく、

、A1A1

そして、X1X1

月00

最初の入力ラインN、M、Knと、M、Kの入力フォーマット

入力MMの次の行

少し不運番号。ああセンは、出力形式は、種の不吉な数数数、出力モジュールKK表示されないと思いました

の結果を取ります。データ範囲0≤Xi、Ai≤90≤Xi、Ai≤9


1≤n≤1091≤n≤109


1≤m≤201≤m≤20


2≤K≤10002≤K≤1000

サンプル入力:100 3. 4
111
出力サンプル:81

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 25;
int n, m, mod;
char str[N];
int ne[N];
int a[N][N];
void mul(int c[][N], int a[][N], int b[][N]){
 static int t[N][N];
 memset(t, 0, sizeof t);
 for (int i = 0; i < m ; i ++)
    for (int j = 0; j < m ; j ++)
       for (int k = 0; k < m; k ++)
     t[i][j] = (t[i][j] + a[i][k] * b[k][j]) % mod;
 memcpy(c, t, sizeof t); 
}
int qmi(int k){
 int f0[N][N] = {1};
 while(k){
  if (k & 1)   mul(f0, f0, a);
  mul(a, a, a);
  k >>= 1;
 }
  int res = 0;
 for (int i = 0; i < m; i ++)   res = (res + f0[0][i]) % mod;
 return res;
}
int main(){
 cin >> n >> m >> mod;
 cin >> str + 1;
 for (int i = 2, j = 0; i <= m; i ++){
  while(j && str[j + 1] != str[i])   j = ne[j];
  if (str[j + 1] == str[i])   j ++;
  ne[i] = j;
 }
 for (int j = 0; j < m; j ++)
     for (int c = '0'; c <= '9'; c ++){
      int k = j;
      while(k && str[k + 1] != c)   k = ne[k];
      if (str[k + 1] == c)   k ++;
      if (k < m)  a[j][k] ++;
  }
  cout << qmi(n) << endl;
 return  0;
}
公開された106元の記事 ウォン称賛67 ビュー5408

おすすめ

転載: blog.csdn.net/qq_45772483/article/details/105052407