题目

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;
}

转载于:https://www.cnblogs.com/WABoss/p/5785052.html

HDU5863 cjj's string game(DP + 矩阵快速幂)相关推荐

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

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

  2. 第九届河南省赛 宣传墙 //状压dp+矩阵快速幂+dfs

    http://nyoj.top/problem/1273 状压dp+矩阵快速幂+dfs 1273-宣传墙 内存限制:64MB 时间限制:1000ms 特判: No 通过数:19 提交数:64 难度:4 ...

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

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

  4. BZOJ 2004 公交线路(状压DP+矩阵快速幂)

    注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...

  5. bzoj 3329: Xorequ(DP+矩阵快速幂)

    3329: Xorequ Time Limit: 1 Sec  Memory Limit: 256 MB Submit: 1134  Solved: 491 [Submit][Status][Disc ...

  6. bzoj 4818: [Sdoi2017]序列计数(DP+矩阵快速幂)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 769  Solved: 463 [Submit][Stat ...

  7. 2018.09.28 hdu5434 Peace small elephant(状压dp+矩阵快速幂)

    传送门 看到n的范围的时候吓了一跳,然后发现可以矩阵快速幂优化. 我们用类似于状压dp的方法构造(1(1(1<<m)∗(1m)*(1m)∗(1<<m)m)m)大小的矩阵. 然后 ...

  8. 骨牌问题(DP+矩阵快速幂)

    在2*N的一个长方形方格中,用一个1*2的骨牌排满方格. 问有多少种不同的排列方法. 例如:2 * 3的方格,共有3种不同的排法.(由于方案的数量巨大,只输出 Mod 10^9 + 7 的结果) In ...

  9. foj2198 Problem 2198 快来快来数一数 dp 矩阵快速幂

    Problem 2198 快来快来数一数 Accept: 67 Submit: 194 Time Limit: 1000 mSec Memory Limit : 65536 KB Problem De ...

  10. CCPC-Wannafly Comet OJ 夏季欢乐赛(2019)E.飞行棋(期望dp+矩阵快速幂)

    题目 飞行棋的规则如下: 1.每名玩家有一个棋子,每个回合可以掷一次骰子. 2.如果使用的骰子为 k面,则这 k面上的点数分别为 1,2,3,-,k,且掷得每种点数的概率均为​. 3.如果当前回合掷得 ...

最新文章

  1. Docker 图形化页面管理工具使用
  2. 【转】POJ 1177 Picture(1)
  3. c++中可以对类中私有成员中的静态变量初始化吗?
  4. java 显示日历_JAVA显示日历(已知年和该年第一天为星期几)
  5. 万能钥匙也不能解开的wifi?那用Python帮你轻松解决
  6. SQL Server Pivot 隐藏group
  7. 简明 Vim 练级攻略 | 酷壳 - CoolShell.cn
  8. colgroup标签
  9. python优先级排序_Python Numpy重新排列双向排序
  10. 集装箱装柜计算机器在线,装箱大师在线计算教程
  11. autoCAD编辑图案填充
  12. 按键精灵_字符串提取
  13. 圈儿里使人泪两行的事儿,千万要注意。
  14. 首次用jwt做token
  15. 纵即逝的烟花蓄势于纸
  16. ATTCK v12版本战术介绍持久化(三)
  17. Django中F对象,Q对象与运算符
  18. django的update和create高级操作
  19. openGauss十月社区运作报告
  20. 第五章 存储数据 web scraping with python

热门文章

  1. Keepalived+HAProxy基于读写分离方式实现discuz论坛
  2. Buffer Pool--内存总结1
  3. .NET/ASP.NET Routing路由(深入解析路由系统架构原理)
  4. 如何去找一些还没有完全上市的 在私募投资的公司 D轮左右 财经媒体
  5. How to publish in an open world?
  6. school and connections
  7. University of Edinburgh
  8. UGUI 事件穿透规则
  9. 快速编辑 Shell 命令行
  10. VIM 使用技巧(常用提取)