• 1009: [HNOI2008]GT考试


    1009: [HNOI2008]GT考试

    Time Limit: 1 Sec Memory Limit: 162 MB
    Submit: 5006 Solved: 3150
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    4 3 100
    111

    Sample Output

    81

    HINT

    Source

    [Submit][Status][Discuss]


    dp思路:处理到每一位时维护前(forall iin[0,m])A的前i项重叠的情况数,dp即可
    kmp处理出不吉利数字的前缀,并建出矩阵。
    快速米求解即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define max(a,b) ((a)>(b) ? (a): (b))
    #define min(a,b) ((a)<(b) ? (a): (b))
    #define LL long long
    using namespace std;
    
    int i,m,n,j,k,a[100001],ans,nex[100001];
    
    struct vv
    {
        int g[30][30];
    } f,d,e;
    
    void cs(vv &a)
    {
        memset(a.g,0,sizeof(a.g));
        for(int i=0;i<m;i++) 
            a.g[i][i]=1;
    }
    
    vv cheng(vv a,vv b,int n,int m,int z)
    {
        vv o;
        memset(o.g,0,sizeof(o.g));
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                for(int l=0;l<z;l++) 
                    o.g[i][j]=(o.g[i][j]%k+a.g[i][l]*b.g[l][j]%k)%k;
            
        return o;
    }
    
    vv ksm(int x)
    {
        vv w;
        cs(w);
        for(;x>1;x>>=1)
        {
            if(x&1) w=cheng(w,f,m,m,m);
            f=cheng(f,f,m,m,m);
        }
        return cheng(f,w,m,m,m);
    }
    
    void kmp()
    {
        int j=0;
        nex[1]=0;
        for(int i=2;i<=m;i++)
        {
            while((j>0)&&(a[i]!=a[j+1])) j=nex[j];
            if(a[i]==a[j+1]) j++;
            nex[i]=j;
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(i=1;i<=m;i++) scanf("%1ld",&a[i]);
        kmp();
        
        for(i=1;i<m;i++)
        {
            int j=i, l=0;
            bool bb[11];
            memset(bb,0,sizeof(bb));
            if(i==m-1) bb[a[m]]=1,l=1;
            while(j)
            {
                if(!bb[a[j+1]])	f.g[i][j+1]=1,l+=1;
                bb[a[j+1]]=1;
            
                j=nex[j];
            }
            if(!bb[a[1]]) f.g[i][1]=1, l+=1;
            f.g[i][0]=10-l;
        }
        f.g[0][1]=1;
        f.g[0][0]=9; 
        d.g[0][0]=1;
        vv t=cheng(d,ksm(n),1,m,m);
        for(i=0;i<m;i++)
        ans=(ans+t.g[0][i])%k;
        printf("%d",ans);
    }
    
  • 相关阅读:
    小菜读书---《程序员修炼之道–从小工到专家》
    小菜读书--《大话设计模式》
    darknet-mini:带注释的darknet简化版,助你深入理解YOLO
    如何使用VLC进行视频录像
    海康相机打开的方法
    YOLOv5训练自己的数据集(超详细完整版)
    用GANs来做数据增强
    torch ----------->>>>rknn
    Linux下的tar压缩解压缩命令详解
    小缺陷目标检测网络--PCB缺陷检测—TDD-net
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9757022.html
Copyright © 2020-2023  润新知