• uva 10518 How Many Calls?


    数学递推(考查矩阵二分快速幂取模)

    参考:http://www.cnblogs.com/staginner/archive/2011/12/14/2288187.html

    输入n和M,简单来说就是要求f(n)%M,而f(n)=2*F(n)-1,F(n)为第n项费波那列数,所以问题转化为求F(n),由于n非常大n (0 <= n < 263-1)

    所以线性递推会超时,要用矩阵快速幂的方法

    初始化[F0,F1]=[0,1] , 要求[Fn,Fn+1]


    [F0,F1]  *  |0 1| (n)  =   [Fn,Fn+1] (不考虑高精度)
                     |1 1|

    用二分的方法求解|0 1| (n)
                            |1 1|

    //初始化[f0,f1],要求[fn,fn+1]
    //[f0,f1] * |0 1| (n)  =   [fn,fn+1]    (不考虑高精度)
    //          |1 1|
    #include <cstdio>
    #include <cstring>
    #define MAX 550
    
    long long b[MAX][2];
    long long N,M;
    
    void pow_mod(long long n ,int c)
    {
        if(n==1)  //递归边界,矩阵为0,1,1,1
        {
            b[c][0]=0;   b[c][1]=1;
            b[c+1][0]=1; b[c+1][1]=1;
            return ;
        }
        pow_mod(n/2,c+2);
        //递归,每次递归都产生一个矩阵,一个矩阵占两行所以c+2
    
        long long A=b[c+2][0] , B=b[c+2][1] , C=b[c+3][0] , D=b[c+3][1];
        b[c][0]=  ( A*A+B*C )%M;
        b[c][1]=  ( A*B+B*D )%M;
        b[c+1][0]=( C*A+D*C )%M;
        b[c+1][1]=( C*B+D*D )%M;
    
        if(n&1) //奇数还要乘上矩阵{0,1,1,1}
        {
            long long tmp;
            tmp=b[c][0];   b[c][0]=b[c][1];     b[c][1]+=tmp;
            tmp=b[c+1][0]; b[c+1][0]=b[c+1][1]; b[c+1][1]+=tmp;
        }
    
        //打印当前矩阵
    //    printf("\n| %lld %lld |\n",b[c][0],b[c][1]);
    //    printf("| %lld %lld |\n",b[c+1][0],b[c+1][1]);
    
        return ;
    }
    
    void solve()
    {
        memset(b,0,sizeof(b));
        //b用来保存递归过程中的矩阵,用空间换取时间
        pow_mod(N,0);
        //矩阵二分快速幂取模
        printf("%lld\n",(2*b[1][1]-1+M)%M);
        //可知F(n)就位于b[1][1]这个位置
    }
    
    int main()
    {
        int T=0;
        while(scanf("%lld%lld",&N,&M)!=EOF)
        {
            if(!N && !M) break;
            printf("Case %d: %lld %lld ",++T,N,M);
            if(!N) printf("0\n");  //特判
            else   solve();
        }
        return 0;
    }
  • 相关阅读:
    hdu 2842 Chinese Rings
    Codeforces Round #118 (Div. 1) A 矩阵快速幂
    hdu2604 Queuing
    支付宝 生活号 获取 userId 和 生活号支付
    maven 项目使用本地jar
    nexus 私有 maven 仓库的搭建
    linux jdk 安装
    gitlab 可以上传代码,但是 不能 上传 tag 问题
    maven 内置变量
    mysql 不允许分组的问题 this is incompatible with sql_mode=only_full_group_by
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2908709.html
Copyright © 2020-2023  润新知