zoukankan      html  css  js  c++  java
  • [HNOI2008] GT考试

    [HNOI2008] GT考试

    标签 : DP 矩阵乘法


    题目链接

    题意

    n位数中不出现一个子串的方案数。

    题解

    (设dp[i][j])为前i位匹配到j时的合法方案数。(所谓合法,就是不能有别的匹配更多或相同)
    然后显然(dp[i][j]=dp[i-1][k]×a[k][j],a[k][j])代表从k位加一个数字j的数字个数。
    然后这是一个线性的递推,直接上矩阵加速。
    最后要求的答案就是 (sum_{i=0}^{m-1} dp[n][i])

    Code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
    #define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
    #define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
    inline int read()
    {
    	int sum=0,p=1;char ch=getchar();
    	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
    	if(ch=='-')p=-1,ch=getchar();
    	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
    	return sum*p;
    }
    
    const int maxn=52;
    int n,m,mod;
    
    struct matrix {
    	int n,m;
    	int g[52][52];
    	void Matrix()
    		{
    			n=m=0;memset(g,0,sizeof(g));
    		}
    	
    	matrix operator * (matrix a)const
    		{
    			matrix b;
    			b.Matrix();
    			b.n=n;b.m=a.m;
    			REP(i,0,b.n-1)
    			{
    				REP(j,0,b.m-1)
    				{
    					REP(k,0,m-1)b.g[i][j]=(b.g[i][j]+g[i][k]*a.g[k][j])%mod;
    				}
    			}
    			return b;
    		}
    		
    };
    char str[maxn];int nxt[maxn];
    
    matrix make_new()
    {
    	matrix a;
    	a.Matrix();
    	a.n=a.m=m;
    	REP(i,0,m-1)
    	{
    		REP(j,0,9)
    		{
    			int x=i;
    			while(x && str[x+1]-'0'!=j)x=nxt[x];
    			if(str[x+1]-'0'==j)a.g[i][x+1]++;
    			else a.g[i][0]++;
    		}
    	}
    	return a;
    }
    
    void init()
    {
    	n=read();m=read();mod=read();
    	cin>>(str+1);
    	str[0]='-';
    	nxt[1]=0;
    	REP(i,2,m)
    	{
    		int j=nxt[i-1];
    		while(j && str[j+1]!=str[i])j=nxt[j];
    		if(str[j+1]==str[i])nxt[i]=j+1;
    		else nxt[i]=0;
    	}
    }
    
    matrix Init(int n)
    {
    	matrix c;
    	c.Matrix();
    	c.n=c.m=n;
    	REP(i,0,n-1)c.g[i][i]=1;
    	return c;
    }
    
    void doing()
    {
    	matrix ans=Init(m),a=make_new();
    	int k=n;
    	while(k)
    	{
    		if(k & 1)ans=ans * a;
    		k>>=1;
    		a=a * a;
    	}
    	ll anss=0;
    	REP(i,0,m-1)anss=(anss+ans.g[0][i])%mod;
    	cout<<anss<<endl;
    }
    
    int main()
    {
    	freopen("input.in","r",stdin);
    	freopen("output.out","w",stdout);
    	init();
    	doing();
    	return 0;
    }
    
    
    
  • 相关阅读:
    oracle 索引
    oracle 子查询因子化 浅谈(with的使用)
    大数据的遐想
    数据挖掘(算法概要链接)
    orcale 修改字段属性
    sql 对一张表进行按照不同条件进行多次统计
    oracle dblink
    oracle作业
    SQL效率的几点心得
    提高SQL语句的性能
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/7492928.html
Copyright © 2011-2022 走看看