GT考试

题目描述

阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0

输入格式

第一行输入N,M,K.接下来一行输入M位的数。 100%数据N<=10^9,M<=20,K<=1000 40%数据N<=1000 10%数据N<=6
 

输出格式

阿申想知道不出现不吉利数字的号码有多少种,输出模 K 取余的结果。

输入输出样例

输入 #1
4 3 100
111
输出 #1
81

我尽力了,但它就是过不了,我能怎么办(切紫题又不是切西瓜······)

 

复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e2+5;
int net[N],n,m,a[N][N],mod;
struct ch
{
    static const int M=21;
    int a[M][M];
    ch()
    {memset(a,0,sizeof(a));}
    ch operator*(ch b)
    {
        ch c;
        for(int i=0;i<M;++i)
        {
            for(int j=0;j<M;++j)
            {
                for(int k=0;k<M;++k)
                c.a[i][j]+=a[i][k]*b.a[k][j],c.a[i][j]%=mod;
            }
        }
        return c;
    }
    ch& operator*=(ch b)
    {
        *this=*this*b;
        return *this;
    }
    ch operator^(int k)
    {
        ch base=*this,ans;
        for(int i=0;i<M;++i)
        ans.a[i][i]=1;
        while(k)
        {
            if(k&1)
            {
                ans*=base;
            }
            base*=base;
            k>>=1;
        }
        return ans;
    }
    ch operator^=(int k)
    {
        *this=*this^k;
        return *this;
    }
    
}ans,res;

void gg(char* P)
{
    net[0]=0;net[1]=0;
    for(int i=1;i<m;i++)
    {
        int j=net[i];
        while(j&&P[i]!=P[j])j=net[j];
        net[i+1]=P[i]==P[j]?j+1:0;
    }
}

void p(char* P)
{
    for(int i=0;i<m;++i)
    for(int j=0;j<=9;++j)
    {
        int k=i;
        while(k&&P[k+1]!=j+'0')k=net[k];
        if(P[k+1]==j+'0')k++;
        if(k<m)res.a[i][k]++;
    }
}

int main()
{
    scanf("%d%d%d",&n,&m,&mod);
    char T[N];
    scanf("%s",T+1);
    gg(T);
    p(T);
    res=res^n;
    ans.a[0][0]=1;
    ans*=res;
    ll sum;
    for(int i=0;i<21;i++){
        sum+=ans.a[0][i];
        sum%=mod;
    }
    printf("%d",sum);
    return 0;
}
复制代码

 

posted @   魂兮龙游  阅读(337)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示