矩阵快速幂 HDOJ 5318 The Goddess Of The Moon

题目传送门

  1 /*
  2     DP::dp[i][k] 表示选择i个字符串,最后一次是k类型的字符串,它由sum (dp[i-1][j]) (a[j], a[k] is ok)累加而来
  3     矩阵快速幂:将n个字符串看成n*n的矩阵,如果匹配,矩阵对应位置为1。矩阵缩短递推dp时间,然后乘m-1次(dp[m][i])累加即可
  4             注意去重
  5     详细解释:http://blog.csdn.net/keshuai19940722/article/details/47111215
  6 */
  7 #include <cstdio>
  8 #include <algorithm>
  9 #include <cstring>
 10 #include <vector>
 11 #include <cmath>
 12 #include <string>
 13 #include <set>
 14 using namespace std;
 15
 16 typedef long long ll;
 17 const int MAXN = 55;
 18 const int INF = 0x3f3f3f3f;
 19 const int MOD = 1e9 + 7;
 20 struct Mat  {
 21     int m[MAXN][MAXN];
 22     Mat () {
 23         memset (m, 0, sizeof (m));
 24     }
 25     void init(void) {
 26         for (int i=0; i<MAXN; ++i)  m[i][i] = 1;
 27     }
 28 };
 29 int n, m;
 30 int a[MAXN];
 31 int dp[MAXN][MAXN];
 32
 33 bool judge(int x, int y)    {
 34     char p[15], q[15];
 35     sprintf (p, "%d", x);
 36     sprintf (q, "%d", y);
 37     int lenp =  strlen (p), lenq = strlen (q);
 38     for (int i=0; i<lenp; ++i)  {
 39         int k = 0;
 40         while (i + k < lenp && k < lenq && p[i+k] == q[k])  k++;
 41         if (i + k == lenp && k >= 2)    return true;
 42     }
 43     return false;
 44 }
 45
 46 Mat operator * (Mat &a, Mat &b) {
 47     Mat ret;
 48     for (int k=1; k<=n; ++k)    {
 49         for (int i=1; i<=n; ++i)    {
 50             for (int j=1; j<=n; ++j)    {
 51                 ret.m[i][j] = (ret.m[i][j] + 1LL * a.m[i][k] * b.m[k][j] % MOD) % MOD;
 52             }
 53         }
 54     }
 55     return ret;
 56 }
 57
 58 Mat operator ^ (Mat x, int n)   {
 59     Mat ret;    ret.init ();
 60     while (n)   {
 61         if (n & 1)  ret = ret * x;
 62         x = x * x;
 63         n >>= 1;
 64     }
 65     return ret;
 66 }
 67
 68 Mat work(void)  {
 69     Mat ret;
 70     for (int i=1; i<=n; ++i)    {
 71         for (int j=1; j<=n; ++j)    {
 72             if (judge (a[i], a[j]))   ret.m[i][j] = 1;
 73         }
 74     }
 75     return ret;
 76 }
 77
 78 void brute_force(void)  {
 79     memset (dp, 0, sizeof (dp));
 80     for (int i=1; i<=n; ++i)    dp[1][i] = 1;
 81     for (int i=2; i<=m; ++i)    {
 82         for (int j=1; j<=n; ++j)    {
 83             for (int k=1; k<=n; ++k)    if (judge (a[j], a[k])) {
 84                 dp[i][k] += dp[i-1][j];
 85                 dp[i][k] %= MOD;
 86             }
 87         }
 88     }
 89     int res = 0;
 90     for (int i=1; i<=n; ++i)    {
 91         res += dp[m][i];    res %= MOD;
 92     }
 93     printf ("%d\n", res);
 94 }
 95
 96 int main(void)  {       //HDOJ 5318 The Goddess Of The Moon
 97     int T;  scanf ("%d", &T);
 98     while (T--) {
 99         scanf ("%d%d", &n, &m);
100         for (int i=1; i<=n; ++i)    {
101             scanf ("%d", &a[i]);
102         }
103         sort (a+1, a+1+n);  n = unique (a+1, a+1+n) - (a + 1);
104
105         //brute_force();
106
107         Mat x = work ();
108         Mat res = x ^ (m - 1);  int ans = 0;
109         for (int i=1; i<=n; ++i)    {
110             for (int j=1; j<=n; ++j)    {
111                 ans = (ans + res.m[i][j]) % MOD;
112             }
113         }
114         printf ("%d\n", ans);
115     }
116
117     return 0;
118 }
时间: 2024-10-23 01:45:07

矩阵快速幂 HDOJ 5318 The Goddess Of The Moon的相关文章

HDOJ 5318 The Goddess Of The Moon 矩阵快速幂

The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 540    Accepted Submission(s): 215 Problem Description Chang'e (嫦娥) is a well-known character in Chinese ancient mytholog

HDU 5318 The Goddess Of The Moon (矩阵快速幂)

题目链接:HDU 5318 The Goddess Of The Moon 题意:给出N串字符串,若是一个字符串的后缀与另一个字符串的前缀相同并且长度大于1,就表示这两个字符串是可以相连的,问M个字符串相连不同方案数为多少. 思路: 1.将输入的字符串预处理存入一个矩阵中,mp[i][j]=1说明str[i]与str[j]能相连,反之,则不能相连. 2.str[i]与str[j]能相连 转化为 i点到j点可达,那么就可以得到一个有向图,长度为M的意思就是 两点之间所走的步数为M的不同走法有多少种

HDU 5318 The Goddess Of The Moon(矩阵快速幂详解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5318 题面: The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 800    Accepted Submission(s): 349 Problem Description Chang'e (嫦

hdu 5318 The Goddess Of The Moon(矩阵快速幂)

题目链接:hdu 5318 The Goddess Of The Moon 将50个串处理成50*50的矩阵,注意重复串. #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 M

hdu 5318 The Goddess Of The Moon 矩阵高速幂

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5318 The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 438    Accepted Submission(s): 150 Problem Description Chang'e (嫦娥) is

【HDOJ 4686】 Arc of Dream (矩阵快速幂)

[HDOJ 4686] Arc of Dream (矩阵快速幂) 两个公式 a(i) = a(i-1)*Ax+Ay b(i) = b(i-1)*Bx+By 求 0~(n-1) 的a(i)*b(i) 初始矩阵为                                       求幂矩阵为 a0                                                      Ax          0           0          0        

HDOJ 6030 矩阵快速幂

链接: http://acm.hdu.edu.cn/showproblem.php?pid=6030 题意: 给一个手链染色,每连续素数个数的珠子中红色不能比蓝的多,问有多少种情况 题解: 公式为f[i]=f[i-1]+f[i-3],类似菲波那切数列,使用矩阵快速幂即可 代码: 31 typedef vector<ll> vec; 32 typedef vector<vec> mat; 33 34 mat mul(mat &A, mat &B) { 35 mat C

HDOJ Arc of Dream 4686【矩阵快速幂】

Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 3126    Accepted Submission(s): 982 Problem Description An Arc of Dream is a curve defined by following function: where a0 = A0 ai =

HDOJ 4549 M斐波那契数列 费马小定理+矩阵快速幂

MF( i ) = a ^ fib( i-1 ) * b ^ fib ( i )   ( i>=3) mod 1000000007 是质数 , 根据费马小定理  a^phi( p ) = 1 ( mod p )  这里 p 为质数 且 a 比 p小 所以 a^( p - 1 ) = 1 ( mod p ) 所以对很大的指数可以化简  a ^ k % p  == a ^ ( k %(p-1) ) % p 用矩阵快速幂求fib数后代入即可 M斐波那契数列 Time Limit: 3000/1000