The Goddess Of The Moon

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 589    Accepted Submission(s): 251

Problem Description
Chang’e (嫦娥) is a well-known character in Chinese ancient mythology. She’s the goddess of the Moon. There are many tales about Chang'e, but there's a well-known story regarding the origin of the Mid-Autumn Moon Festival. In a very distant past, ten suns had risen together to the heavens, thus causing hardship for the people. The archer Yi shot down nine of them and was given the elixir of immortality as a reward, but he did not consume it as he did not want to gain immortality without his beloved wife Chang'e.

However, while Yi went out hunting, Fengmeng broke into his house and forced Chang'e to give up the elixir of immortality to him, but she refused to do so. Instead, Chang'e drank it and flew upwards towards the heavens, choosing the moon as residence to be nearby her beloved husband.

Yi discovered what had transpired and felt sad, so he displayed the fruits and cakes that his wife Chang'e had liked, and gave sacrifices to her. Now, let’s help Yi to the moon so that he can see his beloved wife. Imagine the earth is a point and the moon is also a point, there are n kinds of short chains in the earth, each chain is described as a number, we can also take it as a string, the quantity of each kind of chain is infinite. The only condition that a string A connect another string B is there is a suffix of A , equals a prefix of B, and the length of the suffix(prefix) must bigger than one(just make the joint more stable for security concern), Yi can connect some of the chains to make a long chain so that he can reach the moon, but before he connect the chains, he wonders that how many different long chains he can make if he choose m chains from the original chains.

 
Input
The first line is an integer T represent the number of test cases.
Each of the test case begins with two integers n, m. 
(n <= 50, m <= 1e9)
The following line contains n integer numbers describe the n kinds of chains.
All the Integers are less or equal than 1e9.
 
Output
Output the answer mod 1000000007.
 
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

Hint

11 111 is different with 111 11

 

题目大意:有t组数据。每组数据有n,m。分别表示有n种类型的字串(可能重复),每种字串无限多个。问你如果从这些字串中挑出m个连成一串。问能形成多少种字串。能连接的要求是前边那个串的后缀跟后边那个串的前缀重复最少2个字符。(连接成新的字串时直接连接,不用重叠)。

解题思路:定义dp[i][j]表示选出前i个字串以j字串为结尾的种数。首先定义a[i][j]表示j字串可以连接在i字串后边。dp[i][j]+=dp[i][k]*a[k][j] (1<=k<=n)。然后用矩阵快速幂去优化矩阵相乘。

#include<stdio.h>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
using namespace std;
const int MOD=1000000007;
typedef long long INT;
int n,m;
char str[55][12];
struct Matrix{
int a[55][55];
Matrix(){
memset(a,0,sizeof(a));
}
void init(){
for(int i=1;i<=n;i++)
a[1][i]=1;
}
Matrix operator *(Matrix &X)const {
Matrix ret;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
ret.a[i][j]=(ret.a[i][j]%MOD+((INT)a[i][k]*X.a[k][j])%MOD)%MOD;
}
}
}
return ret;
}
};
Matrix &Pow(Matrix &ret,Matrix a,int x){
while(x){
if(x&1){
ret=ret*a;
}
x>>=1;
a = a * a;
}
return ret;
}
bool check(int x,int y){//检查是否能连接
int lenx=strlen(str[x]),leny=strlen(str[y]);
if(lenx==1||leny==1)
return 0;
for(int i=lenx-2;i>=0;i--){
int ii=i,jj=0;
while(ii<lenx&&jj<leny&&str[x][ii]==str[y][jj]){
ii++,jj++;
}
if(ii==lenx){
return 1;
}
}
return 0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
Matrix A,B;
scanf("%d%d",&n,&m);
set<string>ST;
ST.clear();
for(int i=1;i<=n;i++){
scanf("%s",str[i]);
ST.insert(str[i]);
}
n=0;
for(set<string>::iterator it=ST.begin();it!=ST.end();it++){
strcpy(str[++n],(*it).c_str());
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(check(i,j))
A.a[i][j]=1;
}
}
B.init();
Pow(B,A,m-1);
int res=0;
for(int i=1;i<=n;i++){
res=(res%MOD+B.a[1][i]%MOD)%MOD;
}
printf("%d\n",res); }
return 0;
}

  

下面这个代码时间快得很。

#include<bits/stdc++.h>
using namespace std;
const int MOD=1000000007;
typedef long long INT;
int n,m;
char str[55][12];
struct Matrix{
int a[55][55];
Matrix(){
memset(a,0,sizeof(a));
}
void init(){
for(int i=1;i<=n;i++)
a[1][i]=1;
}
Matrix operator *(Matrix &X)const {
Matrix ret;
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
if(a[i][k])
for(int j=1;j<=n;j++){
if(X.a[k][j])
ret.a[i][j]=(ret.a[i][j]%MOD+((INT)a[i][k]*X.a[k][j])%MOD)%MOD;
}
}
}
return ret;
}
};
Matrix &Pow(Matrix &ret,Matrix a,int x){
// while(x){
// if(x&1){
// ret=ret*a;
// }
// x>>=1;
// a = a * a;
// }
for(;x;x>>=1,a=a*a)
if(x&1)
ret=ret*a;
return ret;
}
bool check(int x,int y){
int lenx=strlen(str[x]),leny=strlen(str[y]);
if(lenx==1||leny==1)
return 0;
for(int i=lenx-2;i>=0;i--){
int ii=i,jj=0;
while(ii<lenx&&jj<leny&&str[x][ii]==str[y][jj]){
ii++,jj++;
}
if(ii==lenx){
return 1;
}
}
return 0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
Matrix A,B;
scanf("%d%d",&n,&m);
set<string>ST;
ST.clear();
for(int i=1;i<=n;i++){
scanf("%s",str[i]);
ST.insert(str[i]);
}
n=0;
for(set<string>::iterator it=ST.begin();it!=ST.end();it++){
strcpy(str[++n],(*it).c_str());
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(check(i,j))
A.a[i][j]=1;
}
}
B.init();
Pow(B,A,m-1);
int res=0;
for(int i=1;i<=n;i++){
res=(res%MOD+B.a[1][i]%MOD)%MOD;
}
printf("%d\n",res); }
return 0;
}

  

HDU 5318——The Goddess Of The Moon——————【矩阵快速幂】的更多相关文章

  1. 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 ( ...

  2. 2015 Multi-University Training Contest 3 hdu 5318 The Goddess Of The Moon

    The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  3. HDU 1757 A Simple Math Problem(矩阵快速幂)

    题目链接 题意 :给你m和k, 让你求f(k)%m.如果k<10,f(k) = k,否则 f(k) = a0 * f(k-1) + a1 * f(k-2) + a2 * f(k-3) + …… ...

  4. HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

    Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  5. (hdu 6030) Happy Necklace 找规律+矩阵快速幂

    题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6030 Problem Description Little Q wants to buy a nec ...

  6. hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!

    http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE,  更重要的是找出规律后,O(n)递推也过不了,TLE,一定 ...

  7. hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***

    分析:假设g(g(g(n)))=g(x),x可能非常大,但是由于mod 10^9+7,所以可以求出x的循环节 求出x的循环节后,假设g(g(g(n)))=g(x)=g(g(y)),即x=g(y),y也 ...

  8. hdu 1757 A Simple Math Problem (矩阵快速幂,简单)

    题目 也是和LightOJ 1096 和LightOJ 1065 差不多的简单题目. #include<stdio.h> #include<string.h> #include ...

  9. 2017ACM暑期多校联合训练 - Team 2 1006 HDU 6050 Funny Function (找规律 矩阵快速幂)

    题目链接 Problem Description Function Fx,ysatisfies: For given integers N and M,calculate Fm,1 modulo 1e ...

随机推荐

  1. 借助百度云API进行人脸识别

    前言:本篇博客是笔者第一次使用百度云api进行人脸检测,主要内容包括两部分,一是获取接口,二是借助接口进行人脸检测.笔者也是初步了解这方面的内容,也是参考了杂七杂八的博文,内容可能存在错误及其他毛病, ...

  2. python 面向对象十一 super函数

    python 面向对象十一 super函数   super函数用来解决钻石继承. 一.python的继承以及调用父类成员 父类: class Base(object): def __init__(se ...

  3. 神奇的Form表单

    今天坐标单上传,提交的按钮使用了<button>,发现不论怎么写ajax和设置form表单,都会刷新页面,百思不得解,然后偶然间把<button>变成<input typ ...

  4. ionic3 IPX留海适配

    解决:使用 safe-area-inset-top 等 ios 安全区域变量 + meta 标签中设置 viewport-fit=cover https://github.com/pengkobe/r ...

  5. Qt 学习之路 2(31):贪吃蛇游戏(1)

    Qt 学习之路 2(31):贪吃蛇游戏(1) 豆子 2012年12月18日 Qt 学习之路 2 41条评论 经过前面一段时间的学习,我们已经了解到有关 Qt 相当多的知识.现在,我们将把前面所讲过的知 ...

  6. Android Activity实例应用(选择QQ头像)

    1.效果图 点击button,跳转到页面2 选择需要的头像,自动返回 3.XML文件布局 页面1 <?xml version="1.0" encoding="utf ...

  7. JAVASCRIPT 使用 && 和 || 完成 简写

    123=='1234' && 'active'    为真时,返回 'active '...可以当成 三元运算符的简写形式哦. let  val = val || 'active'  ...

  8. 洛谷 P2577 [ZJOI2005]午餐

    这道题目比较难想. 题解: 算法:贪心+dp 容易想到贪心:吃饭慢的先打饭节约时间, 所以先将人按吃饭时间从大到小排序. 然后就是dp了: 首先,应该想到f[i][j][k]:前i个人,在1号窗口打饭 ...

  9. Myeclipse经常弹出Subversion Native Library Not Available

  10. Codeforces Round #462 (Div. 2), problem: (C) A Twisty Movement (求可以转一次区间的不递增子序列元素只有1,2)

    题目意思: 给长度为n(n<=2000)的数字串,数字只能为1或者2,可以将其中一段区间[l,r]翻转,求翻转后的最长非递减子序列长度. 题解:求出1的前缀和,2的后缀和,以及区间[i,j]的最 ...