zoukankan      html  css  js  c++  java
  • 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;  
    }  
    

      

  • 相关阅读:
    hdu 4612 Warm up 双连通缩点+树的直径
    Hadoop-04-HBase全然分布式环境搭建
    java实现的Trie树数据结构
    Sharpui企业版-简单介绍【01】 【QQ群:206378966】
    Apache Mina开发手冊之四
    POJ训练计划1459_Power Network(网络流最大流/Dinic)
    svn+ssh
    Android首席设计师宣称移动概念已死,开发人员应该面向屏幕编写应用而非移动
    连锁快餐企业软件的一些管理
    多进程解决datasnap支持的tcp长连接数量少的问题
  • 原文地址:https://www.cnblogs.com/Przz/p/5409809.html
Copyright © 2011-2022 走看看