• HDU1588


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

    题目大意:g(i)= k * i + b. 给定 k 和 b,求0 <= i < n 的斐波那契数 F(g(i))的和模1,000,000,000.

    解题思路:

      矩阵快速幂再加上二分矩阵公式。

      首先,我们需要认识到的一点是:对于这种求斐波那契数的题,很多都是用矩阵快速幂根据如下公式来计算的。

                                             

      我们在此把中间那个01矩阵设为A。要求 The_Sum_of_F(g(i)),只需求出 A^(g(0)-1) + A^(g(1)-1) + A^(g(2)-1) + ... + A^(g(n-1)-1) = A^(b-1) + A^(i+b-1) + A^(2*i+b-1) + ...... = A^(b-1) + A^(b-1) * (A^i + A^(2*i) + A^(3*i) + ......). A^(b-1) = Ab, A^i = Ai,这些都可以用矩阵快速幂求出来。那么式子就变成:Ab+Ab * (Ai + Ai^2 + Ai^3 + ......).加粗的那部分用二分矩阵公式递归求出。下面给出二分矩阵公式的一个例子:A^1+A^2+A^3+A^4+A^5+A^6=(A^1+A^2+A^3)+A^3(A^1+A^2+A^3)。

    AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn = 1000;
     7 struct Matrix {
     8     ll mat[4][4];
     9 };
    10 Matrix E;
    11 ll M;
    12 Matrix Multiply(Matrix x,Matrix y) {    
    13     Matrix temp;
    14     memset(temp.mat, 0, sizeof(temp.mat));
    15     for (int i = 0; i < 2; i++)
    16         for (int j = 0; j < 2; j++) {
    17             for (int k = 0; k < 2; k++) {
    18                 temp.mat[i][j] += (x.mat[i][k] * y.mat[k][j]%M);
    19                 temp.mat[i][j]%=M;
    20             }
    21         }
    22     return temp;
    23 }
    24 Matrix Add(Matrix x,Matrix y){
    25     Matrix temp;
    26     for (int i = 0; i < 2; i++){
    27         for (int j = 0; j < 2; j++) {
    28             temp.mat[i][j]=(x.mat[i][j]+y.mat[i][j])%M;
    29         }
    30     }
    31     return temp;
    32 }
    33 Matrix Fast_Power(Matrix a, int m) {        //求a的m次幂
    34     Matrix res;
    35     memset(res.mat, 0, sizeof(res.mat));
    36     for (int i = 0; i < 2; i++)        res.mat[i][i] = 1;
    37     while (m) {
    38         if (m & 1)    res = Multiply(res, a);
    39         m >>= 1;
    40         a = Multiply(a, a);
    41     }
    42     return res;
    43 }
    44 Matrix Binary_add(Matrix B,int t){
    45     if(t==1)    return B;
    46     if(t%2==1){
    47         return Add(Multiply(Binary_add(B,(t-1)/2),Add(E,Fast_Power(B,(t-1)/2))),Fast_Power(B,t));
    48     }
    49     else
    50         return Multiply(Binary_add(B,t/2),Add(E,Fast_Power(B,t/2)));
    51 }
    52 int main()
    53 {
    54     E.mat[0][0]=E.mat[1][1]=1;
    55     E.mat[0][1]=E.mat[1][0]=0;
    56     Matrix A;
    57     A.mat[0][0]=A.mat[0][1]=A.mat[1][0]=1;
    58     A.mat[1][1]=0;
    59     ll k,b,n,t;
    60     while(scanf("%lld%lld%lld%lld",&k,&b,&n,&M)==4){
    61         Matrix Ab,B,ans;
    62         B=Fast_Power(A,k);
    63         Ab=Fast_Power(A,b);
    64         ans=Add(Ab,Multiply(Ab,Binary_add(B,n-1)));
    65         printf("%lld
    ",ans.mat[1][0]);
    66     }
    67     return 0;
    68 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    requestWindowFeature()的应用(转载)
    Android美工坊selector选择器的使用(转载)
    Activity强制横屏竖屏
    ActivityGroup的简单用法(2)Demo展示讲解
    AndroidGUI25:定制Activity的标题栏(Titlebar)(转载)
    android背景选择器selector用法汇总
    eclipse的注释字体大小如何修改?不改变代码的字体
    QML基础——QML国际化(中文示例)
    QML基础——在C++程序中使用QML
    App for Android (4) —— Eclipse篇
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7367657.html
Copyright © 2020-2023  润新知