HDU

来源:互联网 发布:淘宝魔兽带团本 编辑:程序博客网 时间:2024/06/08 18:52


通过k种不同的字符构造两个长度为n的字符串,要求字符串匹配的最大长度等于m,问有多少种构造方案

先固定第一个串A,有k^n种

对于第二个串B

dp【i】【j】表示构造到第i个字符,且从i-j+1到i和A匹配(也就是说当前匹配了j长度)

n比较大,m比较小,可以使用矩阵快速幂来求,但很明显,这样保证了j<=m,求的是字符串匹配的最大长度小于等于m的方案数,脑短路了一会,怀疑是不是做错了

妈的,直接m-- 再求一遍,两个一减不就是等于m的方案数了


#include<bits/stdc++.h>using namespace std;const int mo=1e9+7;struct node{    long long a[11][11];    node operator * (const node &b)const    {        node c;        memset(c.a,0,sizeof(c.a));        for(int i=0;i<11;i++)        {            for(int j=0;j<11;j++)            {                for(int k=0;k<11;k++)                    c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mo;            }        }        return c;    }}one,cc,yuan;int n,m,k;void init(){    memset(one.a,0,sizeof(one.a));    memset(cc.a,0,sizeof(cc.a));    memset(yuan.a,0,sizeof(yuan.a));    yuan.a[0][0]=1;    for(int i=0;i<=m;i++)        cc.a[i][0]=k-1;    for(int i=0;i<11;i++)    {        one.a[i][i]=1;        if(i<m)        cc.a[i][i+1]=1;    }}node poww(node a,int b){    node c=one;    while(b)    {        if(b&1)            c=c*a;        a=a*a;        b>>=1;    }    return c;}long long poww(long long a,int b){    long long sum=1;    while(b)    {        if(b&1)            sum=(sum*a)%mo;        a=(a*a)%mo;        b>>=1;    }    return sum;}long long solve(){    init();    long long sum=0;    node ans;    ans=yuan*poww(cc,n);    for(int i=0;i<=m;i++)        sum=(sum+ans.a[0][i])%mo;    return sum;}int main(){    int T,i;    cin>>T;    while(T--)    {        cin>>n>>m>>k;        long long sum=solve();        m--;        sum=(sum-solve()+mo)%mo;        sum=(sum*poww(k,n))%mo;        cout<<sum<<endl;    }    return 0;}


原创粉丝点击