zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU 5451 Best Solver(Fibonacci数列 && 快速幂)(2015沈阳网赛1002题)

    Problem Description
    The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart.

    It is known that y=(5+2√6)^(1+2^x).
    For a given integer x (0x<2^32) and a given prime number M (M46337) , print [y]%M . ([y] means the integer part of y )
     
    Input
    An integer T (1<T1000) , indicating there are T test cases.
    Following are T lines, each containing two integers x and M , as introduced above.
     
    Output
    The output contains exactly T lines.
    Each line contains an integer representing [y]%M .
     
    Sample Input
    7
    0 46337
    1 46337
    3 46337
    1 46337
    21 46337
    321 46337
    4321 46337
     
    Sample Output
    Case #1: 97
    Case #2: 969
    Case #3: 16537
    Case #4: 969
    Case #5: 40453
    Case #6: 10211
    Case #7: 17947

    题目大意就是求那个式子y=(5+2√6)^(1+2^x)。

    考虑(5+2√6)^n和(5-2√6)^n;

    分别设为A和B,

    自然A*B=1

    考虑A+B,发现奇数次幂的根号消掉了,于是是个整数。

    由因为A>1,自然B<1所以说A的小数部分就是1-B,所以A的整数部分就是A+B-1。

    于是就是求A+B,便能得到结果。

    而这个式子跟特征根求解的一次线性递推式的结果很像。

    于是考虑x^2+bx+c=0这个特征方程,跟为5+2√6和5-2√6。

    得b=-10,c=1。

    于是递推式为f(n+2)=10f(n+1)-f(n)。

    然后本地打表发现,不管模范围内的任何素数,这个序列的循环节都不是很大。

    于是考虑直接暴力循环节,不过记忆化下来。

    然后就是考虑2^x模循环节的结果即可,这个用快速幂。

    复杂度是O(r+logx),其中r为循环节大小。

    题解中通过结论 (p^2- p)(p^2-1)为循环节使用矩阵快速幂.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    const int maxM = 47000;
    int x, m, r[maxM], f[maxM];
    
    void init()
    {
        if (r[m] != -1)
            return;
        f[0] = 2%m;
        f[1] = 10%m;
        for (int i = 2;; ++i)
        {
            f[i] = ((10*f[i-1]-f[i-2])%m+m)%m;
            if (f[i-1] == f[0] && f[i] == f[1])
            {
                r[m] = i-1;
                break;
            }
        }
    }
    
    //快速幂m^n
    int quickPow(LL x, int n, int mm)
    {
        int a = 1;
        while (n)
        {
            a *= n&1 ? x : 1;
            a %= mm;
            n >>= 1 ;
            x *= x;
            x %= mm;
        }
        return a;
    }
    
    void work()
    {
        int k, ans;
        k = quickPow(2, x, r[m]);
        k = (k+1)%r[m];
        f[0] = 2%m;
        f[1] = 10%m;
        for (int i = 2; i <= k; ++i)
            f[i] = ((10*f[i-1]-f[i-2])%m+m)%m;
        ans = (f[k]-1+m)%m;
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        memset(r, -1, sizeof(r));
        int T;
        scanf("%d", &T);
        for (int times = 0; times < T; ++times)
        {
            printf("Case #%d: ", times+1);
            scanf("%d%d", &x, &m);
            init();
            work();
        }
        return 0;
    }
  • 相关阅读:
    HBase 高性能加入数据
    Please do not register multiple Pages in undefined.js 小程序报错的几种解决方案
    小程序跳转时传多个参数及获取
    vue项目 调用百度地图 BMap is not defined
    vue生命周期小笔记
    解决小程序背景图片在真机上不能查看的问题
    vue项目 菜单侧边栏随着右侧内容盒子的高度实时变化
    vue项目 一行js代码搞定点击图片放大缩小
    微信小程序进行地图导航使用地图功能
    小程序报错Do not have xx handler in current page的解决方法
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4822086.html
Copyright © 2011-2022 走看看