hdu 5564 Clarke and digits (dp+矩阵加速)
来源:互联网 发布:csol显卡优化 编辑:程序博客网 时间:2024/06/07 05:22
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5564
题意:
问题描述
克拉克是一名人格分裂患者。某一天,克拉克变成了一个研究人员,在研究数字。 他想知道在所有长度在[l,r]之间的能被7整除且相邻数位之和不为k的正整数有多少个。
输入描述
第一行一个整数T(1≤T≤5),表示数据的组数。 每组数据只有一行三个整数l,r,k(1≤l≤r≤109,0≤k≤18)。
输出描述
每组数据输出一行一个数,表示答案。由于答案太大,你只需对109+7取模即可。
输入样例
21 2 52 3 5
输出样例
13125
Hint
第一个样例有13个数满足,分别是:7,21,28,35,42,49,56,63,70,77,84,91,98
分析:
定义dp[i][j][k]表示位数为i,当前数%7的值而且以k结尾的方案数。
那么有:
for(int i=1;i<r;i++)
for(int j=0;j<7;j++)
for(int k=0;k<10;k++)
for(int x=0;x<10;x++) if(k+x!=K)
dp[i+1][(j*10+x)%7][x]+=dp[i][j][k];
但是r<=1e9,很大。不能直接递推,需要矩阵快速幂来加速递推。
首先建状态转移图(初始矩阵),mat[s1][s2]表示从状态s1到状态s2的方案数,当前数%7的值为i且以j结尾,s1=i*10+j,添加一个数x,i变为i' ,i'=(i*10+x)%7,j变为j',j'=x,那么状态s2=i'*10+j'。
然后需要多出一列来算累加和。
最后用快速幂直接求解。
代码:
#include <bits/stdc++.h>using namespace std;const int maxn = 72;const int mod = 1e9+7;struct Matrix{int mat[maxn][maxn];Matrix(){memset(mat,0,sizeof(mat));}friend Matrix operator *(const Matrix &A,const Matrix &B);friend Matrix operator ^(Matrix A,int n);};Matrix operator *(const Matrix &A,const Matrix &B) //mul {Matrix ret;for(int i=0;i<maxn;i++)for(int j=0;j<maxn;j++)for(int k=0;k<maxn;k++)(ret.mat[i][j]+=1ll*A.mat[i][k]*B.mat[k][j]%mod)%=mod;return ret;}Matrix operator ^(Matrix A,int n) //pow{Matrix ret;for(int i=0;i<maxn;i++)ret.mat[i][i]=1;for(;n;n>>=1,A=A*A) if(n&1)ret=ret*A;return ret;}inline int Statu(int i,int j){return i*10+j;}int main(){int nCase,i,j,L,R,K;scanf("%d",&nCase);while(nCase--){scanf("%d%d%d",&L,&R,&K);Matrix A,B;for(i=0;i<7;i++)for(j=0;j<10;j++)for(int x=0;x<10;x++) if(j+x!=K)B.mat[Statu(i,j)][Statu((i*10+x)%7,x)]++;for(i=0;i<10;i++)B.mat[Statu(0,i)][maxn-1]++;B.mat[maxn-1][maxn-1]=1;for(i=1;i<10;i++)A.mat[0][Statu(i%7,i)]++;Matrix ret1=A*(B^R);Matrix ret2=A*(B^(L-1));int res=ret1.mat[0][maxn-1]-ret2.mat[0][maxn-1];while(res<0)res+=mod;while(res>=mod)res-=mod;printf("%d\n",res);}return 0;}
1 0
- hdu 5564 Clarke and digits (dp+矩阵加速)
- hdu 5564 Clarke and digits (数位dp + 矩阵快速幂优化)
- hdu 5564 Clarke and digits
- hdu 5564 Clarke and digits(矩阵快速幂)
- hdu 5564 && bestcode 62 Clarke and digits
- HDU 5564:Clarke and digits 收获颇多的矩阵快速幂 + 前缀和
- hdu5564 Clarke and digits
- HDU 5469 Clarke and problem (DP)
- HDU 5464Clarke and problem(DP)
- hdu 5464 Clarke and problem(DP)
- hdu 5464 Clarke and problem dp
- hdu 5464 Clarke and problem(dp)
- [HDU 5411] CRB and Puzzle (矩阵加速DP + 前缀和矩阵|等比求和快速幂 )
- BestCoder Round #62 (div.2) HDOJ5564 Clarke and digits(dp + 快速幂)
- HDU 5464 Clarke and problem(DP 01背包)
- HDU Clarke and points
- Clarke and MST HDU
- hdu5464 Clarke and problem(DP)
- android 快速定位内存泄露位置技巧
- Android中进程与线程
- 轻松把玩HttpClient之模拟post请求示例
- recylerView
- sbt使用自定义仓库
- hdu 5564 Clarke and digits (dp+矩阵加速)
- wtl学习开篇
- 批量删除VC&VS中的临时文件方法
- http压力测试
- 化简问题
- Sublime Text 3 快捷键汇总
- myeclipse删除工程后出现Could not publish to the server
- 虚函数、纯虚函数通俗解释(C++,Java)
- 15-11-16 Eclipse 操作菜单汉译之Edit [编辑]