HDU
Posted hhlya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU相关的知识,希望对你有一定的参考价值。
题面
Problem Description
Lele now is thinking about a simple function f(x).
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
Input
The problem contains mutiple test cases.Please process to the end of file. In each case, there will be two lines. In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 ) In the second line , there are ten integers represent a0 ~ a9.
Output
For each case, output f(k) % m in one line.
Sample Input
10 9999
1 1 1 1 1 1 1 1 1 1
20 500
1 0 1 0 1 0 1 0 1 0
Sample Output
45
104
思路
直接看就是快速幂,我们关注一下这个2*1e9的数据量,这个数据量的话,复杂度肯定要降到log级别的,所以快速幂并木有错误。那么重点还是构造矩阵,我们让第一列是题目给的递推式子,其余为单位偏移作用。做n-9次的快速幂后和f1-f9去相乘就好啦。那么有几个细节注意,矩阵乘法的时候要取两遍的mod,然后最后的矩阵乘法不要写反,矩阵的相乘并不满足交换律,还有就是数组不要开小,会re。这些矩阵快速幂的题目都一个套路,我们真正要做的就是去把题目中隐含的或者直接给的递推式求出来,然后构造相应的辅助矩阵,最后完成快速幂就好。
代码实现
#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
const int inf =0x3f3f3f3f;
const int maxn=11;
struct Matrix {
int maze[maxn][maxn];
Matrix () {
memset (maze,0,sizeof (maze));
}
};
int n,mod;
Matrix mul (Matrix a,Matrix b) {
Matrix ans;
for (int i=1;i<=10;i++)
for (int j=1;j<=10;j++){
for (int k=1;k<=10;k++)
ans.maze[i][j]=(ans.maze[i][j]+(a.maze[i][k]*b.maze[k][j])%mod)%mod;
}
return ans;
}
Matrix fats_pow (Matrix a,int p) {
Matrix ans;
for (int i=1;i<=10;i++) ans.maze[i][i]=1;
while (p) {
if (p&1) ans=mul (ans,a);
a=mul(a,a);
p>>=1;
}
return ans;
}
int main () {
while (cin>>n>>mod) {
Matrix fz;
for (int i=1;i<=10;i++) cin>>fz.maze[i][1];
for (int i=1;i<=9;i++) fz.maze[i][i+1]=1;
if (n<10) {
cout<<n%mod<<endl;
continue;
}
else {
Matrix k;
for (int i=1;i<=10;i++) k.maze[1][i]=10-i;
fz=fats_pow (fz,n-9);
k=mul (k,fz);
cout<<k.maze[1][1]%mod<<endl;
}
}
return 0;
}
以上是关于HDU的主要内容,如果未能解决你的问题,请参考以下文章
POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂