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/Others)
Total Submission(s): 589 Accepted Submission(s): 251

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.
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.
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——————【矩阵快速幂】的更多相关文章
- 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 ( ...
- 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/ ...
- 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) + …… ...
- HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)
Recursive sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- (hdu 6030) Happy Necklace 找规律+矩阵快速幂
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6030 Problem Description Little Q wants to buy a nec ...
- hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!
http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE, 更重要的是找出规律后,O(n)递推也过不了,TLE,一定 ...
- 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也 ...
- hdu 1757 A Simple Math Problem (矩阵快速幂,简单)
题目 也是和LightOJ 1096 和LightOJ 1065 差不多的简单题目. #include<stdio.h> #include<string.h> #include ...
- 2017ACM暑期多校联合训练 - Team 2 1006 HDU 6050 Funny Function (找规律 矩阵快速幂)
题目链接 Problem Description Function Fx,ysatisfies: For given integers N and M,calculate Fm,1 modulo 1e ...
随机推荐
- MongoDB单表导出与导入
mongoexport -h -u dbAdmin -p L-$LpGQ=FJvSf*****([l --authenticationDatabase=project_core_db -d proje ...
- 关于DataGridView的ClearSelection方法
最近做winform项目,遇到一个问题. 纠结了几天,最终解决了,记录一下! 新建一个Form窗体,拽一个DataGridView上去,然后写一个方法 private void BindData() ...
- shell-脚本-作用是发现前10个最占用磁盘空间的文件
#!/bin/bash## 这个脚本的作用是发现前10个最占用磁盘空间的文件################定义这个脚本的全区变量##################################C ...
- Windows NLB搭配IIS的ARR搭建高可用环境(转载)
原文地址:http://www.cnblogs.com/shanyou/archive/2010/04/28/1723276.html 在现行的许多网络应用中,有时一台服务器往往不能满足客户端的要求, ...
- Java create azure web app
create a certificate <java-install-dir>/bin/ keytool -genkey -alias <keystore-id> -keyst ...
- Qt 学习之路 2(51):布尔表达式树模型
Qt 学习之路 2(51):布尔表达式树模型 豆子 2013年5月15日 Qt 学习之路 2 17条评论 本章将会是自定义模型的最后一部分.原本打算结束这部分内容,不过实在不忍心放弃这个示例.来自于 ...
- 创建逻辑卷LVM以及swap分区
#!/bin/bash ##创建逻辑卷LVM /dev/mapper/lvm_data-data### ###default 大小为500G,但是LV一般会比500略小################ ...
- 洛谷 P2059 [JLOI2013]卡牌游戏(概率dp)
题面 洛谷 题解 \(f[i][j]\)表示有i个人参与游戏,从庄家(即1)数j个人获胜的概率是多少 \(f[1][1] = 1\) 这样就可以不用讨论淘汰了哪些人和顺序 枚举选庄家选那张牌, 枚举下 ...
- JSTL的核心标签
JSTL的核心标签: .if: 语法:<c:if test="" var="" scope=""></c:if> 当 ...
- POJ1077 Eight A*
这个题扔到A*可也还行... 定义估价函数h():为每个数或空格的位置 到 最终状态中所在位置 的 曼哈顿距离 的 总和. 把状态压成一个九进制数,便于存储和判重. 然后记录方案可以记录一下此次的操作 ...