HDU5863 cjj's string game(DP + 矩阵快速幂)
题目
Source
http://acm.split.hdu.edu.cn/showproblem.php?pid=5863
Description
cjj has k kinds of characters the number of which are infinite. He wants to build two strings with the characters. The lengths of the strings are both equal to n.
cjj also define a cjj_val for two string.
a[i,j] means the substring a[i],a[i+1],...,a[j-1],a[j] of string a.
cjj_val = max({ j-i+1 }) where a[i,j]=b[i,j] for every 0<=i<=j<n.
Know cjj wants to know that if he wants to build two strings with k different characters whose cjj_val is equal to m, how many ways can he do that.
Input
The first line of the input data is an integer T(1<=T<=100), means the number of test case.
Next T lines, each line contains three integers n(1<=n<=1000000000), m(1<=m<=10), k(1<=k<=26).
Output
For each test case, print one line, the number of the ways to build the string. The answer will be very large, you just need to output ans mod 1000000007.
Sample Input
2
3 2 3
3 3 3
Sample Output
108
27
分析
题目大概说用k个不同的字母,有多少种方法构造出两个长度n最长公共子串长度为m的字符串。
n的规模达到了10亿,而且又是方案数,自然就想到构造矩阵用快速幂解决。
考虑用DP解决可以这么表示状态:
- dp[i][j]表示两个字符串前i个字符都构造好了 并且 它们后面的j个字符相同的方案数
状态的转移就是,末尾j个相同的可以转移到0个相同的也能转移到j+1个相同的(前提是j<m)。
而对于这个状态可以构造矩阵去转移,即一个(m+1)*(m+1)的矩阵,矩阵i行j列表示从末尾i个相同转移到末尾j个相同的方案数,而该矩阵的n次幂的第0行的和就是长度n的字符串末尾各个情况的方案数。
不过样表示状态最后求出来不是要求的,因为LCS小于m的也会包含于其中。那么减去小于m的方案数不就OK了!
- 即 至少包含m个相同公共子串的方案数 - 至少包含m-1个相同公共子串的方案数 = 恰好包含m个相同公共子串的方案数
于是,一样再构造一个m*m的矩阵求n次幂,就OK了。
代码
#include<cstdio>
#include<cstring>
using namespace std; struct Mat{
int m[11][11];
int len;
};
Mat operator*(const Mat &m1,const Mat &m2){
Mat m={0};
m.len=m1.len;
for(int i=0; i<=m.len; ++i){
for(int j=0; j<=m.len; ++j){
for(int k=0; k<=m.len; ++k){
m.m[i][j]+=(long long)m1.m[i][k]*m2.m[k][j]%1000000007;
m.m[i][j]%=1000000007;
}
}
}
return m;
} int main(){
int t,n,m,k;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&k); Mat e={0},me={0};
e.len=m; me.len=m;
for(int i=0; i<=m; ++i) e.m[i][i]=1;
for(int i=0; i<=m; ++i){
if(i<m) me.m[i][i+1]=k;
me.m[i][0]=k*k-k;
}
int exp=n;
while(exp){
if(exp&1) e=e*me;
me=me*me;
exp>>=1;
}
int ans=0;
for(int i=0; i<=m; ++i){
ans+=e.m[0][i];
ans%=1000000007;
} memset(e.m,0,sizeof(e.m));
memset(me.m,0,sizeof(me.m));
e.len=m-1; me.len=m-1;
for(int i=0; i<m; ++i) e.m[i][i]=1;
for(int i=0; i<m; ++i){
if(i<m-1) me.m[i][i+1]=k;
me.m[i][0]=k*k-k;
}
exp=n;
while(exp){
if(exp&1) e=e*me;
me=me*me;
exp>>=1;
}
for(int i=0; i<m; ++i){
ans-=e.m[0][i];
ans%=1000000007;
} if(ans<0) ans+=1000000007;
printf("%d\n",ans);
}
return 0;
}
HDU5863 cjj's string game(DP + 矩阵快速幂)的更多相关文章
- bnuoj 34985 Elegant String DP+矩阵快速幂
题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
[题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*
BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...
- codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)
题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
- poj4474 Scout YYF I(概率dp+矩阵快速幂)
Scout YYF I Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4100 Accepted: 1051 Descr ...
- hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)
http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...
随机推荐
- hdu 2087剪花布条
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 思路:正常KMP求解aaaaaa aa得到的结果是6,这题是3.仅仅改一点代码就行 当匹配完之 ...
- 很少有人会告诉你的Android开发基本常识
原文:很少有人会告诉你的Android开发基本常识. 文章介绍了一些关于开发.测试.版本管理.工具使用等方面的知识.
- Delphi函数参数传递 默认参数(传值)、var(穿址)、out(输出)、const(常数)四类
Delphi的参数可以分为:默认参数(传值).var(传址).out(输出).const(常数)四类 可以对比C/C++的相关知识,类比学习. 1.默认参数是传值,不会被改变,例子 function ...
- Linux Shell 高级编程技巧4----几个常用的shell脚本例子
4.几个常用的shell脚本例子 4.0.在写脚本(同样适用在编程的时候),最好写好完善的注释 4.1.kill_processes.sh(一个杀死进程的脚本) #!/bin/bash c ...
- ExcelReport第二篇:ExcelReport源码解析
导航 目 录:基于NPOI的报表引擎——ExcelReport 上一篇:使用ExcelReport导出Excel 下一篇:扩展元素格式化器 概述 针对上一篇随笔收到的反馈,在展开对ExcelRep ...
- 攻城狮在路上(叁)Linux(二十三)--- linux磁盘参数修改(设备代码、设备名)
一.mknod:设置设备代码 linux中,所有的设备都是用文件来表示,文件通过major与minor数值来判断. major为主设备代码,minor为设备代码(需要查询),示例如下: /dev/hd ...
- JavaScript - 变量,作用域,内存
JavaScript 变量可以用来保存两种类型的值:基本类型值和应用类型值.基本类型的值源自以下5种基本数据类型:Undefined.Null.Bollean.Number和String. 所有变量都 ...
- 为什么接口类型可以直接new?
Runnable rn = new Runnable() { public void run() { } }; 实际相当于,jdk会自动生成一个匿名内部类,完成职责: class Anomymous ...
- GitHub上史上最全的Android开源项目分类汇总 (转)
GitHub上史上最全的Android开源项目分类汇总 标签: github android 开源 | 发表时间:2014-11-23 23:00 | 作者:u013149325 分享到: 出处:ht ...
- 如何hash一条有向边
之前这个问题还困扰了我好久,但是现在我才明白这个很蠢的问题 那就是(3,7)(4,9)(3,3)这种有向序点对(括号可能用的不对) 我们可以变成对"(3,7)"字符串的hash,当 ...