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

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    计算机顶级期刊和会议
    在linux下查看内核版本、gcc版本、操作系统多少位等参数
    GDB调试
    JAVA学习笔记1
    vim下中文乱码问题解决办法
    MATLAB light material lighting
    Matlab2012a第一次安装打不开 查找程序安装类时出错
    vim 安装与运行以及代码的运行
    express 命令汇总
    mongodb 简单命令汇总
  • 原文地址:https://www.cnblogs.com/l609929321/p/9398349.html
Copyright © 2020-2023  润新知