hdu 5564 Clarke and digits (dp+矩阵加速)

来源:互联网 发布:csol显卡优化 编辑:程序博客网 时间:2024/06/07 05:22

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5564

题意:

问题描述
克拉克是一名人格分裂患者。某一天,克拉克变成了一个研究人员,在研究数字。  他想知道在所有长度在[l, r][l,r]之间的能被77整除且相邻数位之和不为kk的正整数有多少个。  
输入描述
第一行一个整数T(1 \le T \le 5)T(1T5),表示数据的组数。  每组数据只有一行三个整数l, r, k(1 \le l \le r \le 10^9, 0 \le k \le 18)l,r,k(1lr109,0k18)
输出描述
每组数据输出一行一个数,表示答案。由于答案太大,你只需对10^9+7109+7取模即可。  
输入样例
21 2 52 3 5
输出样例
13125
Hint
第一个样例有13个数满足,分别是:7,21,28,35,42,49,56,63,70,77,84,91,987,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
原创粉丝点击