Total Submission(s): 144 Accepted Submission(s): 84
Problem Description
Clarke is a patient with multiple personality disorder. One day, Clarke turned into a researcher, did a research on digits.
He wants to know the number of positive integers which have a length in [l,r] and are divisible by 7 and the sum of any adjacent digits can not be k.
He wants to know the number of positive integers which have a length in [l,r] and are divisible by 7 and the sum of any adjacent digits can not be k.
Input
The first line contains an integer T(1≤T≤5),
the number of the test cases.
Each test case contains three integers l,r,k(1≤l≤r≤109,0≤k≤18).
Each test case contains three integers l,r,k(1≤l≤r≤109,0≤k≤18).
Output
Each test case print a line with a number, the answer modulo 109+7.
Sample Input
2
1 2 5
2 3 5
Sample Output
13
125
Hint:
At the first sample there are 13 number $7,21,28,35,42,49,56,63,70,77,84,91,98$ satisfied.
这题先列出dp方程,dp[i][x][ (t*10+x)%7 ]+=dp[i-1][j][t],因为i太大,所以要用矩阵快速幂加速。
可以构造矩阵【dp[i][0][0],dp[i][1][0],..dp[i][0][6],...dp[i][9][6],sum[i-1] 】*A=【dp[i+1][0][0],dp[i+1][1][0],..dp[i+1][0][6],...dp[i+1][9][6],sum[i]】,其中dp[i][j][k]中j表示的是最后一位的数,k表示的是这个数模7后的余数,为了表示前缀和,我们只要把第71列的前10个变为1,dp[70][70]变为1就行了。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define MOD 1000000007
struct matrix{
ll n,m,i;
ll data[72][72];
void init_danwei(){
for(i=0;i<n;i++){
data[i][i]=1;
}
}
};
matrix multi(matrix &a,matrix &b){
ll i,j,k;
matrix temp;
temp.n=a.n;
temp.m=b.m;
for(i=0;i<temp.n;i++){
for(j=0;j<temp.m;j++){
temp.data[i][j]=0;
}
}
for(i=0;i<a.n;i++){
for(k=0;k<a.m;k++){
if(a.data[i][k]>0){
for(j=0;j<b.m;j++){
temp.data[i][j]=(temp.data[i][j]+(a.data[i][k]*b.data[k][j])%MOD )%MOD;
}
}
}
}
return temp;
}
matrix fast_mod(matrix &a,ll n){
matrix ans;
ans.n=a.n;
ans.m=a.m;
memset(ans.data,0,sizeof(ans.data));
ans.init_danwei();
while(n>0){
if(n&1)ans=multi(ans,a);
a=multi(a,a);
n>>=1;
}
return ans;
}
int main()
{
ll n,k,m,i,j,T,l,r,t,x;
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld%lld",&l,&r,&k);
matrix a;
a.n=a.m=71;
memset(a.data,0,sizeof(a.data));
for(t=0;t<=6;t++){
for(j=0;j<=9;j++){
for(x=0;x<=9;x++){
if(x+j!=k){
a.data[j+10*t ][x+(t*10+x)%7*10 ]=1;
}
}
}
}
for(i=0;i<10;i++){
a.data[i][70]=1;
}
a.data[70][70]=1;
matrix a1;
a1.n=a1.m=71;
memset(a1.data,0,sizeof(a1.data));
for(i=0;i<=70;i++){
for(j=0;j<=70;j++){
a1.data[i][j]=a.data[i][j];
}
}
matrix b;
b.n=1;b.m=71;
memset(b.data,0,sizeof(b.data));
for(j=1;j<=9;j++){
b.data[0][j+j%7*10]=1;
}
matrix b1;
b1.n=1;b1.m=71;
memset(b1.data,0,sizeof(b1.data));
for(j=1;j<=9;j++){
b1.data[0][j+j%7*10]=1;
}
ll sum1,sum2;
matrix ans;
ans=fast_mod(a,l-1);
matrix cnt;
cnt=multi(b,ans);
sum1=cnt.data[0][70];
matrix ans1;
ans1=fast_mod(a1,r);
/*
for(i=0;i<=70;i++){
for(j=0;j<=70;j++){
printf("%lld ",ans1.data[i][j]);
}
printf("
");
}
*/
matrix cnt1;
cnt1=multi(b1,ans1);
sum2=cnt1.data[0][70];
printf("%lld
",(sum2-sum1+MOD)%MOD );
}
return 0;
}