2015 多校联赛 ——HDU5302(矩阵快速幂)

The Goddess Of The Moon

Sample Input
2 10 50 12 1213 1212 1313231 12312413 12312 4123 1231 3 131 5 50 121 123 213 132 321
 
Sample Output
86814837 797922656



题意:给你n个字符串,若是一个的后缀与一个的前缀相同的大于1,则表示这两个可以连接到一起,问M个字符串相连的方案数


若a  b可以合并,可以让他们相连,然后求在一个图中走m-1步的方案数,

两点之间所走的步数为m-1的不同走法有多少种——矩阵快速幂的经典问题

因为求不同方案--->去重

(在别人博客看到的,表示以前并不知道这个,既然有点像模板题,写写学习下)


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int maxn = 55;
const int mod = 1e9+7;

int n, m, a[maxn];

struct Mat
{
    int s[maxn][maxn];
    Mat ()
    {
        memset(s, 0, sizeof(s));
    }
    Mat operator * (const Mat& b)
    {
        Mat ret;
        for (int k = 0; k < n; k++)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                    ret.s[i][j] = (ret.s[i][j] + 1LL * s[i][k] * b.s[k][j] % mod) % mod;
            }
        }
        return ret;
    }
};

bool work(int a,int b)
{
    char p[15], q[15];
    sprintf(p, "%d", a);
    sprintf(q, "%d", b);

    int l1 = strlen(p);
    int l2 = strlen(q);
    for(int i = 0; i < l1; i++)
    {
        int k = 0;
        while(i + k < l1 && k < l2 && p[i+k] == q[k])
        {
            k++;
        }
        if(i + k == l1 && k > 1)
            return true;
    }
    return false;
}

Mat solve()
{
    Mat lp;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
        {
            if(work(a[i],a[j]))
                lp.s[i][j] = 1;
        }
    return lp;
}

Mat pow_mat(Mat x, int z)
{
    Mat ret;
    for (int i = 0; i < n; i++)
        ret.s[i][i] = 1;
    while (z)
    {
        if (z&1)
            ret = ret * x;
        x = x * x;
        z >>= 1;
    }
    return ret;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);

        for(int i = 0; i <n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        n = unique(a,a+n) - a;

        if (n == 0 || m == 0)
        {
            printf("0
");
            continue;
        }
        Mat tp = solve();
        Mat tmp = pow_mat(tp,m-1);

        long long ans = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                ans = (long long)(ans + tmp.s[i][j])%mod;
        printf("%I64d
",ans);
    }
}


主要部分:

struct Matrix {  
    LL m[55][55];  
};  
Matrix init;  
  
Matrix MatrixMul(Matrix a, Matrix b){  
    Matrix c;  
    int i,j,k;  
    for(i=0;i<N;i++){  
        for(j=0;j<N;j++){  
            c.m[i][j]=0;  
            for(k=0;k<N;k++){  
                c.m[i][j]+=(a.m[i][k]*b.m[k][j]);  
                c.m[i][j]%=kmod;  
            }  
        }  
    }  
    return c;  
}  
  
Matrix QuickPow(Matrix m,int p){  
    Matrix b;  
    int i;  
    memset(b.m,0,sizeof b.m);  
    for(i=0;i<N;i++)  
        b.m[i][i]=1;  
    while(p){  
        if(p%2) b=MatrixMul(b,m);  
        p/=2;  
        m=MatrixMul(m,m);  
    }  
    return b;  
}  

  

原文地址:https://www.cnblogs.com/Przz/p/5409809.html