您的位置:首页 > 其它

hdu5564 Clarke and digits

2015-12-09 20:20 381 查看
Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

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.

 

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).

 

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("\n");
}
*/

matrix cnt1;
cnt1=multi(b1,ans1);
sum2=cnt1.data[0][70];

printf("%lld\n",(sum2-sum1+MOD)%MOD );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: