http://acm.hdu.edu.cn/showproblem.php?pid=1757
链接镇楼。。
给出f0至f9的初始值,给出fx与其前十项的线性递推公式,求出f的第k项,并对m取模;
k的范围不小 暴力的话会tle 因为线性递推,不难得
fk | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7 | a8 | a9 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
fk-1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
fk-10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
所以,只要先求出f0-f9初始值,构建一个first矩阵,然后根据输入构建一个每次都要乘进去的temp矩阵,求出temp的k-9次幂乘以first所得到的矩阵中的左上角,即【0】【0】处,则为所求fk;
但要注意 当k小于9时,fk已知,所以直接输出取模结果即可。。。
wa了几次。。因为没有在乘法中加入取模。。。。QAQ
一直以为自己第一次写乘法出错了。。还写了个输出函数。。。。
因为是稀疏矩阵,所以乘法可以进行优化。。但本题无此必要。。
下面上代码
#include<cstdio>
#include<cstring>
using namespace std;
int k,m;
typedef long long ll;
struct matrix
{
ll a[10][10];
matrix()
{
memset(a,0,sizeof(a));
for(int i=0;i<10;i++)
a[i][i]=1;
}
};
matrix first;
matrix temp;
matrix mul(matrix a,matrix b)
{
matrix ans;
int i;
int j,k;
for(i=0;i<10;i++){
for(j=0;j<10;j++)
{
ans.a[i][j]=0;
for(k=0;k<10;k++){
ans.a[i][j]+=a.a[i][k]*b.a[k][j]%m;
ans.a[i][j]%=m;
}
}
}
return ans;
}
void print(matrix a)
{
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
printf("%d ",a.a[i][j]);
puts("");
}
puts("");
return ;
}
ll fast_mul(matrix a,matrix b,int c)
{
matrix ans;
//print(ans);
while(c)
{
if(c&1)
ans=mul(b,ans);
b=mul(b,b);
c=c>>1;
}
//print(ans);
ans=mul(ans,a);
//print(a);
//print(ans);
return ans.a[0][0];
}
int main()
{
int i;
for(i=0;i<10;i++){
first.a[i][0]=9-i;
for(int j=1;j<10;j++)
first.a[i][j]=0;
}
while(~scanf("%d%d",&k,&m))
{
for(i=0;i<10;i++){
scanf("%d",&temp.a[0][i]);
if(i)
temp.a[i][i]=0;
if(i<9)
temp.a[i+1][i]=1;
}
//print(first);
// print(temp);
//print(mul(temp,first));
if(k<10){
printf("%d\n",k%m);
continue;
}
ll ans=fast_mul(first,temp,k-9);
printf("%I64d\n",ans%m);
}
return 0;
}
就这样吧