bzoj1009GT考试

题目链接

没啥好说的,矩阵优化+$kmp$字符串匹配

上代码:

/**************************************************************
    Problem: 1009
    User: zhangheran
    Language: C++
    Result: Accepted
    Time:116 ms
    Memory:1300 kb
****************************************************************/
 
#include<iostream>
#include<cstdio>
//#include"suqingnian.h"
#include<algorithm>
#include<cstring>
using namespace std;
int next[30];
int n,m;
int mod;
char a[30];
long long ans;
void nxt()
{
    for(int i=2;i<=m;i++)
    {
        int t=next[i-1];
        while(t&&a[i]!=a[t+1]) t=next[t];
        t+=(a[i]==a[t+1]),next[i]=t;
     }
     return ;
}
struct Martix{
    long long num[30][30];
    friend Martix operator *(const Martix &a,const Martix &b)
    {
        Martix c;
        memset(c.num,0,sizeof(c.num));
        for(int k=0;k<m;k++)
          for(int i=0;i<m;i++)
            for(int j=0;j<m;j++)
              c.num[i][j]=(c.num[i][j]+a.num[i][k]*b.num[k][j]%mod)%mod;
        return c;
    }
    void hint(){memset(num,0,sizeof(num));for(int i=0;i<m;i++) num[i][i]=1;}
    void clear(){memset(num,0,sizeof(num));}
}p;
void kmp()
{
    nxt();
    for(int j=0;j<=9;j++)
      for(int k=0;k<m;k++){
        int t=k;
        while(t&&a[t+1]!=j+'0') t=next[t];
        if(a[t+1]==j+'0') t++;
        p.num[k][t]++;
      }
}
Martix
    _pow(Martix _a,int _b)
    {
        Martix _res;_res.hint();
        for(;_b;_b >>= 1, _a= _a * _a )
          if(_b & 1) _res = _res * _a ;
        return _res ;
    }
int main()
{
    scanf("%d%d%d",&n,&m,&mod);
    scanf("%s",a+1);
    kmp();
    p=_pow(p,n);
//  for(int i=0;i<m;i++,puts(""))
//    for(int j=0;j<m;j++)
//      printf("%lld ",p.num[i][j]);
    for(int i=0;i<m;i++) ans=(ans+p.num[0][i])%mod;
    printf("%lld",ans%mod);
    return 0;
}

 

posted @ 2018-07-25 21:49  米罗偕涯  阅读(243)  评论(0编辑  收藏  举报