zoukankan      html  css  js  c++  java
  • GT考试「HNOI2008」

    题意

    给定一个字符串,求定长的不包含这个字符串的字符串数量。


    思路

    设子状态(dp[i][j])表示求的字符串匹配到i,给定的字符串最多匹配到j的答案数量,那么所求即为(sum dp[n][i]),转移用kmp维护。

    但是这样速度还是不过,观察之后考虑矩阵快速幂。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T> inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    	template<typename T> inline void write (T x) {
    		if (x<0) putchar('-');
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Solve {
    	
    	const int N=22;
    	
    	int n,m,k;
    	char s[N];
    	int next[N];
    	int dp[N][N];
    	struct Matrix {
    		int ans[N][N];
    	}base;
    	
    	inline Matrix operator * (Matrix a,Matrix b) {
    		Matrix c;
    		for (register int i=0; i<m; ++i) {
    			for (register int j=0; j<m; ++j) {
    				c.ans[i][j]=0;
    				for (register int K=0; K<m; ++K) {
    					c.ans[i][j]=(c.ans[i][j]+1ll*a.ans[i][K]*b.ans[K][j]%k)%k;
    				}
    			}
    		}
    		return c;
    	}
    	inline Matrix operator ^ (Matrix a,int p) {
    		Matrix res=a;--p;
    		while (p) {
    			if (p&1) res=res*a;
    			a=a*a,p>>=1;
    		}
    		return res;
    	}
    	inline int insert (char c,int j) {
    		while (j&&s[j+1]!=c) j=next[j];
    		if (s[j+1]==c) ++j;
    		return j;
    	}
    
    	inline void MAIN () {
    		read(n),read(m),read(k),scanf("%s",s+1);
    		for (register int i=2,j=0; i<=m; ++i) {
    			while (j&&s[j+1]!=s[i]) j=next[j];
    			if (s[j+1]==s[i]) ++j;
    			next[i]=j;
    		}
    		for (register int i=0; i<m; ++i) {
    			for (register char c='0'; c<='9'; ++c) {
    				int K=insert(c,i);
    				++base.ans[i][K];
    			}
    		}
    		Matrix ans=base^n;int res=0;
    		for (register int i=0; i<m; ++i) {
    			res=(res+ans.ans[0][i])%k;
    		}
    		write(res);
    	}
    
    }
    
    int main () {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Solve::MAIN();
    }
    
  • 相关阅读:
    12-转盘
    11-UIView与核心动画对比
    10-动画组
    09-转场动画
    08-图片抖动(帧动画)
    07-心跳效果
    06-CABasicAnimation基础核心动画
    05-时钟效果
    计时器延迟 NSTimer和CADisplaylink GCD中的延迟
    ScrollView与UIPageController
  • 原文地址:https://www.cnblogs.com/ilverene/p/11749057.html
Copyright © 2011-2022 走看看