uva10655contemplation!algebra递推

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;
}

 

posted @ 2016-04-29 16:48  哲贤  阅读(242)  评论(0编辑  收藏  举报