UPC4247【数论】普通递归关系
【数论】普通递归关系
时间限制: 1 Sec 内存限制: 128 MB提交: 103 解决: 19
[提交] [状态] [命题人:admin]
题目描述
考虑以下定义在非负整数 n 上的递归关系
![](http://icpc.upc.edu.cn/upload/image/20170819/20170819091325_24312.jpg)
其中 a,b 是满足以下两个条件的常数:
(1) a2+4b>0
(2) |a-sqrt(a2+4b)| <= 2 // sqrt 是根号的意思
给定 f0,f1, a, b 和 n,请你写一个程序计算f(n),可以假定f(n)是绝对值不超过 109 的整数 (四舍五入)。
![](http://icpc.upc.edu.cn/upload/image/20170819/20170819091325_24312.jpg)
其中 a,b 是满足以下两个条件的常数:
(1) a2+4b>0
(2) |a-sqrt(a2+4b)| <= 2 // sqrt 是根号的意思
给定 f0,f1, a, b 和 n,请你写一个程序计算f(n),可以假定f(n)是绝对值不超过 109 的整数 (四舍五入)。
输入
一行依次给出5个数,f0,f1,a,b和n,f0,f1是绝对值不超过109,n是非负整数,不超过109。另外,a、b是满足上述条件的实数,且|a|,|b|<=106。
输出
一个数F(n)
样例输入
0 1 1 1 20
样例输出
6765
一道水题,矩阵快速幂板子题,注意是duoble类型,而且注意神坑数据f1=f0=0
#include <bits/stdc++.h> typedef long long ll; using namespace std; const int N=1e6+5; struct mat { double a[2][2]; mat operator *(const mat &t)const { mat res; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { res.a[i][j]=0.0; for(int k=0;k<2;k++) res.a[i][j]=(res.a[i][j]+a[i][k]*t.a[k][j]); } } return res; } }; mat qpow(mat a,ll b) { mat ans; ans.a[0][0]=ans.a[1][1]=1; ans.a[0][1]=ans.a[1][0]=0; while(b) { if(b&1)ans=ans*a; a=a*a; b>>=1; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); double f1,f0,a,b; ll n; cin>>f0>>f1>>a>>b>>n; if(f0==0&&f1==0) { cout<<0<<endl; return 0; } mat A,B; A.a[0][0]=a; A.a[0][1]=b; A.a[1][0]=1; B.a[0][0]=f1; B.a[1][0]=f0; A=qpow(A,n-1)*B; printf("%.0f\n",A.a[0][0]); return 0; }