bzoj 1009 GT考试

还是套路题,和bzoj1030基本一样

就是多了矩乘优化

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,tot,ans,mod;
char s[105];
bool ed[6005];
struct Tree{
    int son[10];
    int fail;
}tr[6005];
struct node{
    int f[27][27];
}squ,ret;
void build(char b[]){
    int now=0,len=strlen(b+1);
    for(int i=1;i<=len;i++){
        int k=b[i]-'0';
        if(!tr[now].son[k])tr[now].son[k]=++tot;
        now=tr[now].son[k];
    }
    ed[now]=true;
}
void getfail(){
    queue<int>que;
    for(int i=0;i<10;i++){
        if(tr[0].son[i]){
            que.push(tr[0].son[i]);
        }
    }
    while(!que.empty()){
        int u=que.front();
        que.pop();
        for(int i=0;i<10;i++){
            if(!tr[u].son[i]){
                tr[u].son[i]=tr[tr[u].fail].son[i];
                continue;
            }
            tr[tr[u].son[i]].fail=tr[tr[u].fail].son[i];
            que.push(tr[u].son[i]);
        }
    }
}
node mul(node &a,node &b){
    node c;
    memset(c.f,0,sizeof(c.f));
    for(int i=0;i<=tot;i++){
        for(int j=0;j<=tot;j++){
            for(int k=0;k<=tot;k++){
                c.f[i][j]+=(a.f[i][k]*b.f[k][j])%mod;
                c.f[i][j]%=mod;
            }
        }
    }
    return c;
}
void fast_pow(int x){
    while(x){
        if(x%2){
            ret=mul(ret,squ);
        }
        x/=2;
        squ=mul(squ,squ);
    }
}
void DP(){
    for(int i=0;i<=tot;i++){
        if(ed[i])continue;
        for(int j=0;j<=9;j++){
            if(!ed[tr[i].son[j]])squ.f[i][tr[i].son[j]]+=1;
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&mod);
    scanf("%s",s+1);build(s);
    getfail();DP();
    ret=squ;
    fast_pow(n-1);
    for(int i=0;i<=tot;i++){
        if(!ed[i]){
            (ans+=ret.f[0][i])%=mod;
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lnxcj/p/9716272.html