20130707 hdu4565 So Easy! 数学头脑+矩阵快速幂

教训:

因为:

1.矩阵中会牵扯到负数

2.牵扯到取模

所以:最后的结果可能为负!要记得调整成正的!!!

hdu4565

Fn=(a+sqrt(b))^n+(sqrt(b)-a)^n  是整数!就等于Sn。
F(0) = 2, F(1) = 2*a. 特征根就是 lamda = a+(-)sqrt(b)

递推方程是F(n+2) + (-2a) F(n+1) + (a^2-b)F(n) = 0   (真心没想到这步。。)

 

矩阵:
Fn+2        2a  b-a^2    *   Fn+1
Fn+1    =  1   0                Fn

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
long long int a,b,n,m;
struct matrix
{
    long long int tz[2][2];
}origin;

void prt(matrix const &a)
{
    for(int i=0;i<2;++i)
    {
        for(int j=0;j<2;++j)
            cout<<a.tz[i][j]<<' ';
        cout<<endl;
    }
}
matrix multi(const matrix &a,const matrix &b)
{
    matrix tmp;
    memset (tmp.tz,0,sizeof(tmp.tz));
    for (int i=0;i<2;++i)
        for (int j=0;j<2;++j)
        {
            for (int l=0;l<2;++l)
                tmp.tz[i][j]+=a.tz[i][l]*b.tz[l][j];
            tmp.tz[i][j]%=m;
        }
    return tmp;
}
void cal (long long int n)
{
    matrix now;
    memset (now.tz,0,sizeof(now.tz));
    now.tz[0][0]=now.tz[1][1]=1%m;
    while (n)
    {
        if (n&1)
            now=multi(now,origin);
        n>>=1;
        origin=multi(origin,origin);
    }
  //  prt(now);
    long long int ans=(now.tz[0][0]*2*a+now.tz[0][1]*2)%m;
    cout<<(ans>=0?ans:ans+m)<<endl;
}
int main ()
{
    while(cin>>a>>b>>n>>m)
    {
    origin.tz[0][0]=(2*a)%m;
    origin.tz[0][1]=(b-a*a)%m;
    origin.tz[1][0]=1%m;
    origin.tz[1][1]=0;
  //  prt(origin);
    if (n==0) cout<<2%m<<endl;
    else if (n==1) cout<<(2*a)%m<<endl;
    else cal(n-1);
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值