• [BZOJ1009][HNOI2008]GT考试(KMP+DP)


    [不稳定的传送门

    Solution

    dp[i][j]表示前i个字符当前匹配到不吉利串的第j个,即当前方案的后缀等于不吉利串前缀

    然而由于n过大,不能直接转移,用矩阵优化

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    char s[120];
    int n,m,mo,nex[120];
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    struct info{
    	int n,m,A[30][30];
    	info(int a,int b):n(a),m(b){memset(A,0,sizeof(A));}
    	int *operator [](int x){return A[x];}
    	friend info operator *(info a,info b){
    		info c(a.n,b.m);
    		for(int i=0;i<c.n;++i)
    			for(int j=0;j<c.m;++j)
    				for(int k=0;k<a.m;++k)
    					c[i][j]=(c[i][j]+1ll*a[i][k]*b[k][j]%mo)%mo;
    		return c;
    	}
    };
    
    info Pow(info A,int c){
        info res(A.n,A.m);
        for(int i=0;i<res.n;++i) res[i][i]=1;
        for(;c;c>>=1,A=A*A) if(c&1) res=res*A;
        return res;
    }
    
    void Init(){
    	n=read(),m=read(),mo=read();
    	scanf("%s",s+1);
    	for(int i=2,j=0;i<=m;++i){
    		while(j&&s[i]!=s[j+1]) j=nex[j];
    		if(s[i]==s[j+1]) ++j;
    		nex[i]=j;
    	}
    }
    
    void solve(){
    	info a(m,m);
    	for(int i=0;i<m;++i)
    		for(char j='0';j<='9';++j){
    			int k=i;
    			while(k&&s[k+1]!=j) k=nex[k];
    			if(s[k+1]==j) k++;
    			if(k!=m) a[i][k]++;
    		}
    	info Ans(1,m),tmp=Pow(a,n);
    	Ans[0][0]=1;
    	Ans=Ans*tmp;
    	int sum=0;
    	for(int i=0;i<m;++i)
    		(sum+=Ans[0][i])%=mo;
    	printf("%d
    ",sum);
    }
    
    int main(){Init();solve();return 0;}
    
  • 相关阅读:
    Python电影投票系统
    Python打印一个等边三角形
    打印正直角三角形
    MySQL指令
    MySQL安装 8.0.15版本
    局部变量 全局变量
    目录
    格式化输出
    转义字符
    ffmpeg 从内存中读取数据(或将数据输出到内存)
  • 原文地址:https://www.cnblogs.com/void-f/p/8992188.html
Copyright © 2020-2023  润新知