hdu 4565 So Easy!

          数学。看了Siriuslzx大牛的解释才理解的:http://www.cnblogs.com/lzxskjo/archive/2013/05/27/3100828.html

          对于式子(a + sqrt(b))^ n 二项式分解可得 (a + sqrt ( b ))^ n  = x + y * sqrt( b ) 。且有   (a - sqrt ( b ))^ n  = x - y * sqrt( b ) ,(二项分解即可知)。

因为(a-1)2< b < a所以 0 < (a - sqrt ( b ))^ n  = x - y * sqrt( b ) < 1, 于是有 : x - 1 < y * sqrt( b ) < x;所以答案就等于x + y * sqrt( b )  = 2 * x;求 x 的时候可以直接对(a + sqrt(b))^ n 进行快速幂求解。因为存在 (x + y * sqrt( b )) * (x + y * sqrt( b ) ) = (x * x + y * y * b + (x * y * 2) * sqrt( b ));仔细理解一下快速幂就可以自己推出快速幂了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))

using namespace std;

const int N = 110;

int main()
{
    LL a, b, n, m, ansx, ansy, tx, ty, tmpx, tmpy;
    while(scanf("%I64d%I64d%I64d%I64d", &a, &b, &n, &m) != EOF)
    {
        ansx = 1;ansy = 0; tx = a;ty = 1;
        while(n)
        {
            if(n & 1)
            {
                tmpx = (ansx * tx + ansy * ty * b) % m;
                tmpy = (ansx * ty + ansy * tx) % m;
                ansx = tmpx;ansy = tmpy;
            }
            tmpx = (tx * tx + ty * ty * b) % m;
            tmpy = (tx * ty * 2) % m;
            tx = tmpx, ty = tmpy;
            n >>= 1;
        }
        printf("%I64d\n", ansx * 2 % m);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值