标签:
/*
数位DP题,设dp[n][k][j]为前n位最后一位是k时mod为j的个数。操作都相同,可以使用矩阵加速。本来对于每一位是7*10,可以把它压向一个向量。
加速矩阵为70*70,再加一维计算前缀和即可。
*/
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define LL long long using namespace std; const int MOD=1e9+7; struct Matrix{ int a[75][75]; }; int l,r,K; Matrix T; void set(Matrix &p){ for(int i=0;i<=70;i++) p.a[i][i]=1; } Matrix mul(Matrix a,Matrix b){ Matrix c; for(int i=0;i<=70;i++){ for(int j=0;j<=70;j++){ c.a[i][j]=0; for(int k=0;k<=70;k++){ c.a[i][j]=((LL)c.a[i][j]+(LL)a.a[i][k]*(LL)b.a[k][j])%MOD; } } } return c; } void clear(Matrix &C){ for(int i=0;i<=70;i++){ for(int j=0;j<=70;j++) C.a[i][j]=0; } } int getId(int i,int j){ return i+j*7; } Matrix power(Matrix p,int c){ Matrix res; clear(res);set(res); while(c){ if(c&1) res=mul(res,p); c>>=1; p=mul(p,p); } return res; } void getT(){ clear(T); for(int i=0;i<7;i++){ for(int j=0;j<=9;j++){ for(int k=0;k<10;k++){ if(j+k==K) continue; int x=(i*10+k)%7; T.a[getId(i,j)][getId(x,k)]++; } } } for(int i=0;i<10;i++) T.a[getId(0,i)][70]++; T.a[70][70]=1; } int main(){ int tt; scanf("%d",&tt); while(tt--){ scanf("%d%d%d",&l,&r,&K); getT(); Matrix res; clear(res); for(int i=1;i<10;i++){ res.a[0][getId(i%7,i)]++; } Matrix tmp=mul(res,power(T,r)); int ans=tmp.a[0][70]; tmp=mul(res,power(T,l-1)); ans=(((LL)ans-(LL)tmp.a[0][70])%MOD+MOD)%MOD; cout<<ans<<endl; } }
标签:
原文地址:http://www.cnblogs.com/jie-dcai/p/4982282.html