NYOJ301 递推求值(矩阵快速幂)
来源:互联网 发布:拍拍交友软件聊天 编辑:程序博客网 时间:2024/04/29 08:27
题目:
递推求值
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
给你一个递推公式:
f(x)=a*f(x-2)+b*f(x-1)+c
并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。
注意:-1对3取模后等于2
- 输入
- 第一行是一个整数T,表示测试数据的组数(T<=10000)
随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。
其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9) - 输出
- 输出f(n)对1000007取模后的值
- 样例输入
21 1 1 1 0 51 1 -1 -10 -100 3
- 样例输出
5999896
- 来源
- 经典题目
- 上传者
- 张云聪
这是一道矩阵快速幂的入门加模板题
矩阵快速幂:
1:思想
矩阵快速幂的思想就是跟数的快速幂一样,假如我们要求2^11,次方,我们可以把 11 写成 1+2+8 ,也就是2^0 + 2^1 + 2^3 。那么把一个O(n)的时间复杂度降到了log(n)
矩阵快速幂的思想和数的快速幂是一模一样的,就是要自己实现矩阵的乘法,然后可以套数的快速幂的模板。
2:难点
矩阵题目的难点在于构造矩阵,一般用于有能够推出递推式的题目,推出递推式之后,发现递推O(n)的复杂度时间比较大,那么我们可以构造一个矩阵,然后用矩阵快速幂降低到log(n)的时间复杂度
代码:
#include <cstdio>#include <cstring>#include <cctype>#include <string>#include <set>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 1000007#define N 3#define M 1000000+10#define ll long longusing namespace std;struct Matrix{ ll mat[N][N];};Matrix unit_matrix={ 1,0,0, 0,1,0, 0,0,1};//单位矩阵Matrix mul(Matrix a,Matrix b)//矩阵相乘{ Matrix res; for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) { res.mat[i][j]=0; for(int k=0; k<N; ++k) res.mat[i][j]=(res.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod; } return res;}Matrix pow_matrix(Matrix a,ll n)//矩阵快速幂{ Matrix res=unit_matrix; while(n) { if(n&1) res=mul(res,a); a=mul(a,a); n>>=1; } return res;}int main(){ ll t,f1,f2,a,b,c,n; Matrix tmp,arr; scanf("%lld",&t); while(t--) { scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&n); if(n==1) printf("%lld\n",(f1+mod)%mod); else if(n==2) printf("%lld\n",(f2+mod)%mod); else { mem(arr.mat,0); mem(tmp.mat,0); arr.mat[0][0]=f2,arr.mat[0][1]=f1,arr.mat[0][2]=1;//构造初始矩阵 tmp.mat[0][0]=b,tmp.mat[1][0]=a,tmp.mat[2][0]=c; tmp.mat[0][1]=tmp.mat[2][2]=1; Matrix p=pow_matrix(tmp,n-2); p=mul(arr,p);//注意p和arr不要写反了 ll ans=(p.mat[0][0]+mod)%mod; printf("%lld\n",ans); } } return 0;}
2017/10/10重做代码:
#include<cstdio>#include<cstring>#include<string>#include<set>#include<iostream>#include<stack>#include<queue>#include<vector>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 1000007#define debug() puts("what the fuck!!!")#define ll long longusing namespace std;const ll N=3;struct Matrix{ll a[N][N];Matrix(){mem(a,0);}void init(){mem(a,0);for(ll i=0; i<N; i++)a[i][i]=1;}};void print(Matrix a){for(ll i=0; i<N; i++){for(ll j=0; j<N; j++)printf("%d ",a.a[i][j]);puts("");}}Matrix mul(Matrix a,Matrix b){Matrix ans;for(ll i=0; i<N; i++)for(ll j=0; j<N; j++)for(ll k=0; k<N; k++){ans.a[i][j]=(ans.a[i][j]%mod+a.a[i][k]*b.a[k][j]%mod)%mod;}return ans;}Matrix mat_pow(Matrix a,ll n){Matrix ans;ans.init();while(n){if(n&1)ans=mul(ans,a);a=mul(a,a);n>>=1;}return ans;}int main(){ll f1,f2,a,b,c,n,t;scanf("%lld",&t);while(t--){scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&n);if(n==1)printf("%lld\n",(f1+mod)%mod);else if(n==2)printf("%lld\n",(f2+mod)%mod);else{Matrix A;A.a[0][0]=b,A.a[1][0]=a,A.a[2][0]=c;A.a[0][1]=A.a[2][2]=1;Matrix p=mat_pow(A,n-2);Matrix B;B.a[0][0]=f2,B.a[0][1]=f1;B.a[0][2]=1;Matrix ans=mul(B,p);printf("%lld\n",(ans.a[0][0]+mod)%mod);}}return 0;}
0 0
- nyoj301递推求值【矩阵快速幂】
- 【矩阵快速幂】nyoj301 递推求值
- NYOJ301 递推求值(矩阵快速幂)
- nyoj301 递推求值(矩阵快速幂)
- NYOJ301递推求值 NYOJ 1000又见斐波那契数列(矩阵快速幂)
- nyoj301 递推求值
- NYOJ301-递推求值
- nyoj301递推求值
- nyoj301-递推求值(矩阵模乘)
- 快速矩阵幂NYOJ301
- nyoj301——递推求值
- NYOJ - 301 - 递推求值 ( 递推+矩阵快速幂 )
- 蓝桥杯:递推求值(快速幂,矩阵快速幂)
- nyoj 301递推求值(矩阵快速幂的递推求值)
- NYOJ 301 递推求值(矩阵快速幂)
- nyoj 301递推求值 (矩阵+快速幂)
- nyoj--301 递推求值(矩阵快速幂)
- NYOJ 301 递推求值【矩阵快速幂】
- C语言概述(5)
- 经典查找算法
- 阿里针对布局方案和布局复用的开源框架(VirtualLayout)
- Python面试题汇总
- 【Linux】使用vim编写一个程序,gcc查看预处理、编译、汇编、链接过程
- NYOJ301 递推求值(矩阵快速幂)
- 多线程提高系列(1)--线程的优势以及风险性
- 用户登录密码保存
- deepin
- 面向对象的学习--腾讯课堂,
- SqlServer查询详解
- hadoop配置超详细版
- 如何在 TensorFlow 中用深度学习修复图像?(附论文)
- java读取 其他服务接口 返回的json数据