hdu5564
這道題一看就知道用數位dp,但是在狀態轉移時,發現不可能轉移成功,10^9,但是發現轉移可以用矩陣來進行表示,因此……
但是要注意矩陣最後一列用來計算結果。代碼看看就好了,畢竟卡着時間過的,2500ms左右,標程3000ms.
//hdu 5564 快速矩陣冪+數位dp
#include<stdio.h>
#include<cstdlib>
#include<istream>
#define mod 1000000007
#define long long ll
using namespace std;
struct Mat
{
int on[72][72];
void init()
{
int i, j;
for (i = 0;i <= 71;i++)
for (j = 0;j <= 71;j++)
this->on[i][j] = 0;
}
friend Mat operator*(Mat a, Mat b);
friend Mat operator^(Mat a, int n);
};
Mat operator*(Mat a, Mat b)
{
Mat res;
res.init();
int i, j, l;
for (i = 0;i <= 70;i++)
for (j = 0;j <= 70;j++)
for (l = 0;l <= 70;l++)
{
res.on[i][j] = (res.on[i][j] +(1ll*a.on[i][l]*b.on[l][j])%mod) % mod;
}
return res;
}
Mat operator^(Mat a, int n)
{
Mat b;
b.init();
int i;
for (i = 0;i <= 70;i++)
b.on[i][i] = 1;
while (n)
{
if (n % 2)
{
b = b*a;
}
a = a*a;
n = n / 2;
}
return b;
}
int main()
{
int T;
//freopen("d:\\in.txt", "r", stdin);
scanf("%d", &T);
while (T--)
{
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
Mat a,b;
a.init();
b.init();
int i,j,t;
for (i = 1;i <= 9;i++)
a.on[0][i%7*10+i] = 1;
for (i = 0;i <= 6;i++)
for (j = 0;j <= 9;j++)
for (t = 0;t <= 9;t++)
{
if ((j + t) != k)
b.on[i*10+j][(i*10+t)%7*10+t] = 1;
}
for (i = 0;i <= 9;i++)
b.on[i][70] = 1;
b.on[70][70] = 1;
Mat a1, a2;
a1.init();
a2.init();
a1 = a*(b ^ (l - 1));
a2 = a*(b^r);
printf("%d\n", (a2.on[0][70] - a1.on[0][70]+mod)%mod);
}
return 0;
}