您的位置:首页 > 其它

hdu 5564 快速矩阵幂+数位dp

2015-12-10 20:42 267 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: