HDU 4565 So Easy! 广义斐波拉数 数论 (a+sqrt(b))^n%mod 模板

Posted l609929321

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4565 So Easy! 广义斐波拉数 数论 (a+sqrt(b))^n%mod 模板相关的知识,希望对你有一定的参考价值。

So Easy!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5905    Accepted Submission(s): 1966


Problem Description
  A sequence Sn is defined as:
技术分享图片

Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.
  You, a top coder, say: So easy! 
技术分享图片
 

 

Input
  There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 215, (a-1)2< b < a2, 0 < b, n < 231.The input will finish with the end of file.
 

 

Output
  For each the case, output an integer Sn.
 

 

Sample Input
2 3 1 2013 2 3 2 2013 2 2 1 2013
 

 

Sample Output
4 14 4
 

 

Source
 

 

Recommend
zhoujiaqi2010   |   We have carefully selected several similar problems for you:  6331 6330 6329 6328 6327 
 
求x=(a+sqrt(b))向上取整
求Sn=x^n%mod
 
记(a+sqrt(b))为An,(a-sqrt(b))为Bn
根据题目中对b的限定( (a-1)2< b < a)
有Sn=An+Bn=((a+sqrt(b))^n+(a-sqrt(b))^n)%mod
技术分享图片

 综述得到一个递推式S(n) = 2*a*S(n-1)+(b-a*a)*S(n-2)   这个公式对所有如 (a+sqrt(b))^n%mod形式求整数的式子都适应

我们只需要用矩阵快速幂求这个递推式就行

参考博客:https://blog.csdn.net/chen_ze_hua/article/details/52072732

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ls (r<<1)
#define rs (r<<1|1)
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 2;   //数组的大小尽量开的小,开大了会tle!!!
const ll mod = 1e9 + 7;
struct matrix {
    ll a[maxn][maxn];
};
matrix ans, base;
ll m;
matrix mul( matrix x, matrix y ) {
    matrix tmp;
    for( ll i = 0; i < 2; i ++ ) {
        for( ll j = 0; j < 2; j ++ ) {
            tmp.a[i][j] = 0;
            for( ll k = 0; k < 2; k ++ ) {
                tmp.a[i][j] = ( tmp.a[i][j] + x.a[i][k]*y.a[k][j] + m ) % m;
            }
        }
    }
    return tmp;
}
ll qow( ll n ) {
    while( n ) {
        if( n&1 ) {
            ans = mul( ans, base );
        }
        base = mul( base, base );
        n /= 2;
    }
    return ans.a[0][0];
}
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll a, b, n;
    while( cin >> a >> b >> n >> m ) {
        double tmp = a + sqrt(b);
        ll t1 = (ll)(tmp+1), t2 = (ll)(tmp*tmp+1);
        base.a[0][0] = 2*a, base.a[0][1] = 1;
        base.a[1][0] = (b-a*a+m)%m, base.a[1][1] = 0;
        ans.a[0][0] = t2, ans.a[0][1] = t1;
        ans.a[1][0] = 0, ans.a[1][1] = 0;
        if( n == 1 ) {
            cout << t1 << endl;
        } else if( n == 2 ) {
            cout << t2 << endl;
        } else {
            cout << qow(n-2) << endl;
        }
    }
    return 0 ;
}

  









以上是关于HDU 4565 So Easy! 广义斐波拉数 数论 (a+sqrt(b))^n%mod 模板的主要内容,如果未能解决你的问题,请参考以下文章

hdu4565---So Easy!(矩阵)

HDU4565 So Easy!

So Easy! HDU - 4565

hdu4565 So Easy!(矩阵快速幂)

HDU4565 So Easy! 矩阵高速幂外加数学

构造共轭函数+矩阵快速幂HDU 4565 So Easy! (2013 长沙赛区邀请赛)