HDU 1757 A Simple Math Problem
来源:互联网 发布:linux 改主机名 编辑:程序博客网 时间:2024/06/07 00:54
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.
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.
10 99991 1 1 1 1 1 1 1 1 120 5001 0 1 0 1 0 1 0 1 0
45104
一般矩阵乘法采用朴素的O(n^3)的算法:
Mat operator*(Mat a,Mat b){
int i,j,k;
Mat c;
for (i=0;i<len;i++)
{
for (j=0;j<len;j++)
{
c.mat[i][j] = 0;
for(k=0;k<len;k++)
c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%MOD;
}
}
return c;
}
在ACM的题目中,我们一般考虑的是n阶方阵之间的乘法以及n阶方阵与n维向量(把向量看成n×1的矩阵)的乘法。矩阵乘法最重要的性质就是满足结合律,同时它另一个很重要的性质就是不满足交换率,这保证了矩阵的幂运算满足快速幂取模(A^x % MOD)算法:
假设k = 27,则k的二进制表示为11011,所以
,可以看出:k的二进制的每一位矩阵A都要平方,在k二进制为1的位:末矩阵×平方后的A,在k二进制为0的位则末矩阵×E(单位矩阵),即不变。代码如下:
{
Mat p = e,q = a;
while (x)
{
if(x&1)
p = p*q;
x>>=1;
q = q*q;
}
return p;
}
许多题目还要求S = A + A2 + A3 + … +Ak.。其实再作一次二分即可:只需计算log(n)个A的幂即可。
Mat solve(Mat a,int p)
{
if(p==1)
return a;
/*如果p为奇数,则对p-1进行二分,a^p+二分结果*/
/*
A^1+A^2+A^3+A^4+A^5+A^6+A^7 = (A^1+A^2+A^3)+ A^3*(A^1+A^2+A^3)+A^7=A^7+solve(A,p-1)
*/
else if(p&1)
return (a^p)+solve(a,p-1);
/*p为偶数,则直接二分*/
/*
A^1+A^2+A^3+A^4+A^5+A^6 = (A^1+A^2+A^3)+ A^3*(A^1+A^2+A^3) = (A^3+e)*(A^1+A^2+A^3)
推广即可得到当p为偶数时 A^1+A^2+A^3+……+A^p = (A^(p/2)+e) * solve(A,p/2);
*/
else
return ((a^(p>>1))+e)*solve(a,p>>1);
}
|f(10) | |a0 a1 a2 ...a8 a9| |f(9)|
| f(9) | | 1 0 0 ... 0 0| |f(8)|
| .....| = |.. ... ... ... ..| | .. |
| f(2) | | 0 0 0 ... 0 0| |f(1)|
| f(1) | | 0 0 0 ... 1 0| |f(0)|
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<stack>#include<set>#include<map>#include<queue>#include<algorithm>using namespace std;struct stu{ int mtr[10][10];}a,b,c;int m;int n;struct stu mult(struct stu a1,struct stu a2){ struct stu temp; int i,j,k; for(i=0;i<10;i++){ for(j=0;j<10;j++){ temp.mtr[i][j]=0; for(k=0;k<10;k++){ temp.mtr[i][j]+=(a1.mtr[i][k]*a2.mtr[k][j])%m; } temp.mtr[i][j]%=m; } } return temp;};struct stu bin(int cnt){ struct stu tmp; if(cnt==1) return a; if(cnt%2==0){ tmp=bin(cnt/2);return mult(tmp,tmp); } else{ tmp=bin((cnt-1)/2); tmp=mult(tmp,tmp); return mult(tmp,a); }};int main(){ int i,j,k; while(~scanf("%d %d",&n,&m)){ memset(a.mtr,0,sizeof(a.mtr)); for(i=1;i<10;i++) a.mtr[i][i-1]=1; for(i=0;i<10;i++) scanf("%d",&a.mtr[0][i]); if(n<10){ printf("%d\n",n%m); continue; } n-=9; c=bin(n); int ans=0; for(i=0;i<10;i++) ans+=(c.mtr[0][i]*(9-i))%m; printf("%d\n",ans%m); } return 0;}
- HDU 1757 A Simple Math Problem
- HDU 1757 A Simple Math Problem
- hdu 1757 A Simple Math Problem
- Hdu 1757 A Simple Math Problem
- A Simple Math Problem hdu 1757
- HDU-1757A Simple Math Problem
- HDU 1757 A Simple Math Problem
- hdu 1757:A Simple Math Problem
- hdu 1757 A Simple Math Problem
- hdu 1757 A Simple Math Problem
- hdu 1757 A Simple Math Problem 矩阵
- hdu 1757 A Simple Math Problem
- hdu 1757 A Simple Math Problem 矩阵
- HDU 1757 A Simple Math Problem
- 【HDU 1757 A Simple Math Problem】+ 矩阵
- HDU 1757 A Simple Math Problem
- HDU 1757A Simple Math Problem
- HDU:1757 A Simple Math Problem
- eclipse部署到tomcat出现class not found异常
- SQL Server 数据库迁移方法——备份还原
- 【linux】磁盘管理
- append
- AOP面向切面编程(AOP是Aspect Oriented Program的首字母缩写)
- HDU 1757 A Simple Math Problem
- Qt 实现脉搏检测-1-心跳曲线部分
- 自定义ViewGroup,子View可对换位置
- 文章标题
- 关注
- jquery通过ajax-json访问java后台传递参数,通过request.getParameter获取不到参数的说明
- Android开发——EditText编辑框设计一个登录页面
- UGUI—Button功能的实现
- 产品经理的核心价值和工作边界