http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87585#overview
题意:分别给出a+b的和a*b的值,输出a的n次方加b的n次方的值。
思路:看到题后,认为a+b和a*b联立就可解出a和b的值,a的n次方加b的n次方就得出了,但是这样只能解出整数解,a和b值的数域不止局限于整数,虽然题目结果要求是整数,但是非整数也可得出整数。
(an-1+bn-1)(a+b)=an+abn-1+an-1b+bn
f(n)=an+bn
f(n-1)(a+b)=f(n)+a*b*f(n-2),p=a+b,q=a*b.
p*f(n-1)=f(n)+q*f(n-2)
f(n)=p*(n-1)-q*f(n-2)
则
(f(n-2) f(n-1))A=(f(n-1) f(n))
推出:A=(0 –q
1 p)
(f(0) f(1))An-1=(f(n-1) f(n))
f(0)=2,f(1)=p
部分矩阵题推出递推公式后即可解决,本题的递推公式为(f(0) f(1))An-1=(f(n-1) f(n)),则A为{0,-q,1,p},其中p为a,b的和,q为其积,题的思路即将A的n-1次方得出后用(f(0) f(1))乘以矩阵的第二排。
#include<iostream> #include<cstring> using namespace std; typedef long long ll; struct Matrix { ll v[2][2]; }; Matrix m; Matrix mul(Matrix a,Matrix b) { Matrix c; c.v[0][0]=a.v[0][0]*b.v[0][0]+a.v[0][1]*b.v[1][0]; c.v[0][1]=a.v[0][0]*b.v[0][1]+a.v[0][1]*b.v[1][1]; c.v[1][0]=a.v[1][0]*b.v[0][0]+a.v[1][1]*b.v[1][0]; c.v[1][1]=a.v[1][0]*b.v[0][1]+a.v[1][1]*b.v[1][1]; return c; } Matrix pow(Matrix d,int n) { if(n==1) return d; Matrix e=pow(d,n>>1); if(n%2)return mul(mul(e,e),m); else return mul(e,e); } int main() { int p,q,n; while(cin>>p>>q>>n) { if(n==0){cout<<2<<endl;continue;} if(n==1){cout<<p<<endl;continue;} m.v[0][0]=0;m.v[0][1]=-1*q; m.v[1][0]=1;m.v[1][1]=p; Matrix ans=pow(m,n-1); cout<<2*ans.v[0][1]+p*ans.v[1][1]<<endl; } return 0; }