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

来源:互联网 发布:域名如何绑定云主机 编辑:程序博客网 时间:2024/06/05 19:55

The Goddess Of The Moon

Sample Input
210 5012 1213 1212 1313231 12312413 12312 4123 1231 3 1315 50121 123 213 132 321
 

Sample Output
86814837797922656



题意:给你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\n");            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\n",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;  }  



0 0
原创粉丝点击