题目

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 + 矩阵快速幂)的更多相关文章

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

  2. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  3. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  4. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  5. BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*

    BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...

  6. Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】

    题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...

  7. codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)

    题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...

  8. [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)

    [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...

  9. poj4474 Scout YYF I(概率dp+矩阵快速幂)

    Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4100   Accepted: 1051 Descr ...

  10. hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)

    http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...

随机推荐

  1. ios tableview 适配横竖屏

    tableview.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

  2. September 3rd 2016 Week 36th Saturday

    Calculation never made a hero. 举棋不定,难以称雄. We change. We have to. Or we spend the rest of our lives f ...

  3. c语言强制类型转换

    一.强制类型转换 printf("3/2+100.5=%f",3/2+100.5);//100.5错误表达 printf ("    (float)3/(float)2 ...

  4. Linux C程序内存空间

    linux下内存空间布置: 一个典型的Linux C程序内存空间由如下几部分组成: 代码段(.text).这里存放的是CPU要执行的指令.代码段是可共享的,相同的代码在内存中只会有一个拷贝,同时这个段 ...

  5. .net学习之Attribute特性和EF关键知识点

    一.Attribute特性/标签1.Attribute用来对类.属性.方法等标注额外的信息,贴一个标签简单的说,定制特性Attribute,本质上就是一个类,它为目标元素提供关联附加信息,并在运行时以 ...

  6. 为什么是 n(n+1)/2 ?

    n(n+1)/2是一个数列的元素两两运算后的不重复结果数.如图: 假如数列a = 1,2,3....n.那么该数列内的元素两两相乘,则会构建出上图中的表格,这个表格应该有n x n 个元素. 用程序写 ...

  7. Mishka and Interesting sum Codeforces Round #365 (树状数组)

    树状数组,与Turing Tree类似. xr[i]表示从1到i的抑或,树状数组维护从1到i每个数只考虑一次的异或,结果为sum(r) ^ sum(l) ^ xr[r] ^ xr[l] 其中xr[r] ...

  8. hibernate查询语句实例代码

    一.聚集函数的使用: avg(...), sum(...), min(...), max(...) count(*) count(...), count(distinct ...), count(al ...

  9. JqueryEasyUI 解决IE下datagrid无法刷新的问题 分类: JavaScript JqueryEasyUI 2014-09-20 10:05 510人阅读 评论(1) 收藏

    问题描述: 在使用JqueryEasyUI 时,发现在IE下$('#table').datagrid('reload');无效,数据并没有被刷新,究其原因,是因为刷新时,datagrid请求的url没 ...

  10. JavaScript获取当前根目录

    JavaScript获取当前根目录 主要用到Location 对象,包含有关当前 URL 的信息,是 Window 对象的一个部分,可通过 window.location 属性来访问. 方法一 (wi ...