HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )
题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数
分析 :
直觉是DP
不过当时看到 n 很大、但是 m 很小的时候
发现此题DP并不合适、于是想可能是某种组合数学的问题可以直接公式算
看到题解的我、恍然大悟、对于这种数据、可以考虑一下矩阵快速幂优化的DP
首先要想到线性递推的 DP 式子
最直观的想法就是 dp[i][j] = 到第 i 个位置为止、前面最长匹配长度为 j 的方案数
但是如果仔细想想、这样子的定义状态并不好转移、遂换一种思路
定义 dp[i][j] = 到第 i 个位置为止、以第 i 个字符为结尾的匹配串的长度为 j 的方案数
有转移
dp[i][0] = (dp[i-1][0] + dp[i-1][1] + .... + dp[i-1][m] ) * k * (k-1) (k * (k-1) 的意义是a、b串第 i 个字符不一样的方案数)
dp[i][j] = dp[i-1][j-1] * k ( j ≤ i )
然后尝试去构造矩阵、此处引用 链接
但是注意一下这里的 DP 意义、答案最后并不是 dp[n][m]
dp[n][0] + dp[n][1] + ... + dp[n][m] 可以看成到第 n 个位置为止匹配长度 ≤ m 的方案数
那么如果可以得到匹配长度 ≤ m-1 的方案数两者相减就可以得到匹配长度恰为 m 的方案数了
所以做两次矩阵快速幂即可
#include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define scl(i) scanf("%lld", &i) #define scll(i, j) scanf("%lld %lld", &i, &j) #define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k) #define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l) #define scs(i) scanf("%s", i) #define sci(i) scanf("%d", &i) #define scd(i) scanf("%lf", &i) #define scIl(i) scanf("%I64d", &i) #define scii(i, j) scanf("%d %d", &i, &j) #define scdd(i, j) scanf("%lf %lf", &i, &j) #define scIll(i, j) scanf("%I64d %I64d", &i, &j) #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k) #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k) #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k) #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l) #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l) #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l) #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define lowbit(i) (i & (-i)) #define mem(i, j) memset(i, j, sizeof(i)) #define fir first #define sec second #define VI vector<int> #define ins(i) insert(i) #define pb(i) push_back(i) #define pii pair<int, int> #define VL vector<long long> #define mk(i, j) make_pair(i, j) #define all(i) i.begin(), i.end() #define pll pair<long long, long long> #define _TIME 0 #define _INPUT 0 #define _OUTPUT 0 clock_t START, END; void __stTIME(); void __enTIME(); void __IOPUT(); using namespace std; ; ; struct MAT{ LL val[][]; int sz; MAT(){}; MAT(, sizeof(val)); } friend MAT operator * (const MAT & A, const MAT & B){ MAT C(A.sz); ; k <= C.sz; k++) ; i <= C.sz; i++){ ) continue; ; j <= C.sz; j++){ C.val[i][j] = C.val[i][j] + A.val[i][k] * B.val[k][j] % mod; if(C.val[i][j] >= mod) C.val[i][j] -= mod; } } return C; } }; MAT pow_mod(MAT a, LL b) { MAT ret(a.sz); ; i<=ret.sz; i++) ret.val[i][i] = ; while(b){ ) ret = ret * a; a = a * a; b >>= ; }return ret; } LL Cal(int n, int m, int k) { MAT A(m+); ; i<=A.sz; i++) A.val[][i] = 1LL * k * (k - ); ; i<=A.sz; i++) A.val[i][i-] = k * 1LL; A = pow_mod(A, n); LL ret = ; ; i<=A.sz; i++) ret = (ret + A.val[i][]) % mod; return ret; } int main(void){__stTIME();__IOPUT(); int nCase; sci(nCase); while(nCase--){ int n, m, k; sciii(n, m, k); printf(, k) + mod) % mod); } __enTIME();;} void __stTIME() { #if _TIME START = clock(); #endif } void __enTIME() { #if _TIME END = clock(); cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl; #endif } void __IOPUT() { #if _INPUT freopen("in.txt", "r", stdin); #endif #if _OUTPUT freopen("out.txt", "w", stdout); #endif }
HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )的更多相关文章
- HDU 3802 矩阵快速幂 化简递推式子 加一点点二次剩余知识
求$G(a,b,n,p) = (a^{\frac {p-1}{2}}+1)(b^{\frac{p-1}{2}}+1)[(\sqrt{a} + \sqrt{b})^{2F_n} + (\sqrt{a} ...
- HDU 5863 cjj's string game (矩阵乘法优化递推)
题目大意:用k种字符构建两个长度为n的字符串(每种字符有无限多个),要求对应位置字符相同的连续子串最长长度为m,问方法数. 其中k,n,m是输入,n(1<=n<=1000000000), ...
- HDU 5863 cjj's string game
$dp$,矩阵加速. 设$dp[i][j][0]$表示:长度为$i$的两个字符串,之前还未出现过长度为$m$相同的,目前为止最后$j$个是相同的. 设$dp[i][j][1]$表示:长度为$i$的两个 ...
- hdu 5564 Clarke and digits 矩阵快速幂优化数位dp
Clarke and digits Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- BNUOJ 34985 Elegant String 2014北京邀请赛E题 矩阵快速幂
题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 题目大意:问n长度的串用0~k的数字去填,有多少个串保证任意子串中不包含0~k的 ...
- Recursive sequence HDU - 5950 (递推 矩阵快速幂优化)
题目链接 F[1] = a, F[2] = b, F[i] = 2 * F[i-2] + F[i-1] + i ^ 4, (i >= 3) 现在要求F[N] 类似于斐波那契数列的递推式子吧, 但 ...
- 2018.10.16 uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂优化dp)
传送门 一道不错的矩阵快速幂优化dpdpdp. 设f[i][j][k][l]f[i][j][k][l]f[i][j][k][l]表示前iii轮第iii轮还有jjj个一滴血的,kkk个两滴血的,lll个 ...
- HDU——4291A Short problem(矩阵快速幂+循环节)
A Short problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- 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 ...
随机推荐
- 2019牛客多校第七场E Find the median 权值线段树+离散化
Find the median 题目链接: https://ac.nowcoder.com/acm/contest/887/E 题目描述 Let median of some array be the ...
- matplotlib 画图中的basemap安装问题
在我用matplotlib画图是会用到,basemap这个库,但是直接安装却会出现问题: 使用这条安装命令就能够安装功能了: conda install -c conda-forge basemap= ...
- mysqldump原理及实战
使用mysqldump命令行工具创建逻辑备份: 注意mysqldump的版本和路径mysqldump命令创建的是逻辑备份,结果集有两种格式:一种是将数据转换成标准的SQL语句(一堆CREATE,DRO ...
- cygwin gcc 编译windowsAPI 报错的一个解决方案
一开始按照linux的习惯去编译一个使用了windowsAPI的程序 结果提示: $ i686-pc-cygwin-g++ screen_catch.cscreen_catch.c: In funct ...
- POJ 2485 Prim 找最长的边
A国没有高速公路,因此A国的交通很困难.政府意识到了这个问题并且计划建造一些高速公路,以至于可以在不离开高速公路的情况下在任意两座城镇之间行驶. A国的城镇编号为1到N, 每条高速公路连接这两个城镇, ...
- Java组合模式(思维导图)
图1 组合模式[点击查看图片] 1,以公司职员为例的结构 package com.cnblogs.mufasa.demo3; import java.util.ArrayList; import ja ...
- C# 委托 、事件、同步、异步知识点归纳
一.委托 基本用法: 1.声明一个委托类型.委托就像是‘类'一样,声明了一种委托之后就可以创建多个具有此种特征的委托.(特征,指的是返回值.参数类型) public delegate void Som ...
- 异常:Invalid character found in the request target. The valid characters are defined in RFC 3986
一.背景 事情是这样的,前几天做一个基本的数据库“增删改查”的需求,前端传参的方式是“JSON字符串”,后端接收到此参数后,使用阿里巴巴fastjson进行解析,然后入库.需求很简单吧,但是偏偏遇到问 ...
- 关于如何查看 MySQL 信息、查看Oracle 版本
方法一: 进入mysql cmd, mysql -u root status; 将显示当前mysql的version的各种信息. 方法二: 还是在mysql的cmd下,输入: select versi ...
- 【原型模式】--重写原型对象prototype的影响
//[原型模式]--重写原型对象prototype的影响 2014-12-12//定义构造函数function Person() { }//直接指定构造函数的原型为一个对象(为了简化逐个给原型添加成员 ...