题目链接:点击打开链接
一开始以为只要用求根公式求出a,b然后就用常数快速幂就可以解决。
然而想的太简单了,题目只说p,q是整数,但a,b有可能是实数,所以不能用简单的求根
公式来做。
f(n) = a^n+b^n
f(n-1) = a^(n-1)+b^(n-1)
-f(n-1)*(a+b) = a*b^(n-1)+b*a^(n-1)+f(n)
--f(n-1)*(a+b) = a*b*b^(n-2)+a*b*a^(n-2)+f(n)
---f(n-1)*(a+b) = a*b*(a^(n-2)+b^(n-2))+f(n)
因为:a+b = p, a*b = q
-----p*f(n-1) = q*f(n-2)+f(n)
------f(n) = p*f(n-1)-q*f(n-2)
得到递推式:f(n) = p*f(n-1)-q*f(n-2)
然后构造矩阵即可。
注意题目没说p,q都为0时输入结束(输出0即可)...而是读到文件结束。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
ll s[2][2];
node() {}
node(ll a, ll b, ll c, ll d)
{
s[0][0] = a;
s[0][1] = b;
s[1][0] = c;
s[1][1] = d;
}
};
node mul(node a, node b)
{
node t = node(0, 0, 0, 0);
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 2; k++)
t.s[i][j] = (t.s[i][j]+a.s[i][k]*b.s[k][j]);
return t;
}
node mt_pow(node p, ll n)
{
node q = node(1, 0, 0, 1);
while(n)
{
if(n&1) q = mul(p, q);
p = mul(p, p);
n /= 2;
}
return q;
}
int main(void)
{
ll p, q, n;
while(cin >> p >> q >> n)
{
if(n == 0) puts("2");
else if(n == 1) printf("%lld\n", p);
else
{
node base = node(p, -q, 1, 0);
node ans = mt_pow(base, n-1);
printf("%lld\n", ans.s[0][0]*p+ans.s[0][1]*2);
}
}
return 0;
}