hdu5318The Goddess Of The Moon 矩阵快速幂

来源:互联网 发布:修改oracle默认端口 编辑:程序博客网 时间:2024/05/16 06:48
//n(<=50)种字符串,每一种字符串的个数不限//前一个字符串s的后缀与后一个字符串t相同且长度大于1//那么两个字符串可以连接在一起,//那么选m(<=1e9)个字符串连接在一起有多少种情况//建立一个可连接矩阵,直接快速幂就行,注意一下字符串去重#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>using namespace std ;const int maxn = 51 ;typedef long long ll ;const ll mod = 1e9+7 ;string str[maxn] ;int n , m ;struct node{    ll p[maxn][maxn] ;};node mul(node a , node b){    node c ;    memset(c.p , 0 , sizeof(c.p)) ;    for(int i = 1;i <= n;i++)       for(int j = 1;j <= n;j++)          for(int k = 1;k <= n;k++)          c.p[i][j] = (c.p[i][j] + a.p[i][k]*b.p[k][j])%mod ;    return c ;}node pow(node a , int k){    node c ;    memset(c.p , 0 , sizeof(c.p)) ;    for(int i = 1;i <= n;i++)    c.p[i][i] = 1  ;    while(k)    {        if(k&1)c = mul(a,c) ;        a = mul(a, a) ;        k>>=1 ;    }    return c ;}bool judge(string s , string t){    int len = s.length() ;    for(int i = 2;i <= t.length();i++){        if(len < i)return false ;        bool flag = false ;        for(int k = 0;k < i;k++)        if(s[len-i+k]!=t[k]){           flag = true ;           break ;        }        if(!flag)return true ;    }    return false ;}int main(){    //std::ios_base::sync_with_stdio(false);    int t ;    scanf("%d" , &t) ;    while(t--)    {        scanf("%d%d" , &n , &m) ;        for(int i = 1;i <= n;i++)        cin>>str[i] ;        if(m<2){          cout<<m<<endl;          continue ;        }        sort(str+1 , str+1+n) ;        n = unique(str+1 , str+1+n) - str - 1 ;        node a ;        memset(a.p , 0 , sizeof(a.p)) ;        for(int i = 1;i <= n;i++)           for(int j = 1;j <= n;j++)           a.p[i][j] = judge(str[i] , str[j]) ;        a = pow(a , m-1) ;        ll ans= 0 ;        for(int i = 1;i <= n;i++)          for(int j = 1;j <= n;j++)          ans = (ans + a.p[i][j])%mod ;        cout<<ans<<endl ;    }}

0 0
原创粉丝点击