【矩阵+共轭构造】HDU - 4565 - So Easy!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/82902111

题目链接<http://acm.hdu.edu.cn/showproblem.php?pid=4565>


题意:

求出:

0< a, m < 215, (a-1)^{2}< b < a^{2}, 0 < b, n < 231


题解:

首先从(a+\sqrt{b})^{n}入手,很容易发现它的构成是X+Y\sqrt b的形式。

假设(a+\sqrt{b})^{n}=X+Y\sqrt b,那么(a+\sqrt{b})^{n+1}=(X+Y\sqrt b)*(a+\sqrt{b})=(Xa+Yb)+(aY+X)\sqrt b

所以可以构造出矩阵:\begin{pmatrix} a &b \\ 1 &a \end{pmatrix}.

还有一个向上取整的问题,这题利用共轭来构造出答案,否则精度会有问题。

因为(a-1)^{2}< b < a^{2},所以0<a-\sqrt b<1,所以0<(a-\sqrt b)^{n}<1

利用二项式展开可以得出:(a+\sqrt{b})^{n}+(a-\sqrt{b})^{n}=2X,所以2X就是答案。


#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
ll s[2][2],p[2][2],q[2][2],m;
void mul(ll a[2][2],ll b[2][2]){
    ll c[2][2];
    memset(c,0,sizeof(c));
    for(ll i=0;i<2;i++)
        for(ll j=0;j<2;j++)
            for(ll k=0;k<2;k++)
                c[i][j]=(c[i][j]+a[i][k]*b[k][j])%m;
    memcpy(b,c,sizeof(c));
}
void mpow(ll t){
    for(ll i=t;i;i>>=1,mul(p,p)){
        if(i&1) mul(p,s);
    }
}
int main(){
    ll n,a,b;
    while(scanf("%lld%lld%lld%lld",&a,&b,&n,&m)!=EOF){
        p[0][0]=a;p[0][1]=b;
        p[1][0]=1;p[1][1]=a;
        s[0][0]=a;s[1][0]=1;
        mpow(n-1);
        printf("%lld\n",s[0][0]*2%m);
    }
}

猜你喜欢

转载自blog.csdn.net/monochrome00/article/details/82902111