zoukankan      html  css  js  c++  java
  • HDU 1005 Number Sequence:矩阵快速幂

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

    题意:

      数列{f(n)}: f(1) = 1, f(2) = 1, f(n) = ( A*f(n-1) + B*f(n-2) ) MOD 7

      给定A、B、n,求f(n)。 (1<=n<=100,000,000)

    题解:

      大水题~ (*/ω\*)

      矩阵快速幂。

      

      初始矩阵start:

      

      特殊矩阵special:

      

      所求矩阵ans:

        ans = start * special^(n-1)

      ans的第一项即为f(n)。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #define MAX_L 5
      5 #define MOD 7
      6 
      7 using namespace std;
      8 
      9 struct Mat
     10 {
     11     int n;
     12     int m;
     13     int val[MAX_L][MAX_L];
     14     Mat()
     15     {
     16         n=0;
     17         m=0;
     18         memset(val,0,sizeof(val));
     19     }
     20 };
     21 
     22 int a,b,n;
     23 
     24 Mat make_unit(int n)
     25 {
     26     Mat mat;
     27     mat.n=n;
     28     mat.m=n;
     29     for(int i=0;i<n;i++)
     30     {
     31         mat.val[i][i]=1;
     32     }
     33     return mat;
     34 }
     35 
     36 Mat make_start()
     37 {
     38     Mat mat;
     39     mat.n=1;
     40     mat.m=2;
     41     mat.val[0][0]=1;
     42     mat.val[0][1]=1;
     43     return mat;
     44 }
     45 
     46 Mat make_special()
     47 {
     48     Mat mat;
     49     mat.n=2;
     50     mat.m=2;
     51     mat.val[0][0]=0;
     52     mat.val[0][1]=b;
     53     mat.val[1][0]=1;
     54     mat.val[1][1]=a;
     55     return mat;
     56 }
     57 
     58 Mat mul_mat(const Mat &a,const Mat &b)
     59 {
     60     Mat c;
     61     if(a.m!=b.n)
     62     {
     63         cout<<"Error: mat_mul"<<endl;
     64         return c;
     65     }
     66     c.n=a.n;
     67     c.m=a.m;
     68     for(int i=0;i<a.n;i++)
     69     {
     70         for(int j=0;j<b.m;j++)
     71         {
     72             for(int k=0;k<a.m;k++)
     73             {
     74                 c.val[i][j]+=a.val[i][k]*b.val[k][j];
     75                 c.val[i][j]%=MOD;
     76             }
     77         }
     78     }
     79     return c;
     80 }
     81 
     82 Mat quick_pow_mat(Mat mat,long long k)
     83 {
     84     Mat ans;
     85     if(mat.n!=mat.m)
     86     {
     87         cout<<"Error: quick_pow_mat"<<endl;
     88         return ans;
     89     }
     90     ans=make_unit(mat.n);
     91     while(k)
     92     {
     93         if(k&1)
     94         {
     95             ans=mul_mat(ans,mat);
     96         }
     97         mat=mul_mat(mat,mat);
     98         k>>=1;
     99     }
    100     return ans;
    101 }
    102 
    103 int main()
    104 {
    105     while(cin>>a>>b>>n)
    106     {
    107         if(a==0 && b==0 && n==0) break;
    108         Mat start=make_start();
    109         Mat special=make_special();
    110         Mat ans=mul_mat(start,quick_pow_mat(special,n-1));
    111         cout<<ans.val[0][0]<<endl;
    112     }
    113 }
  • 相关阅读:
    vue打包报错
    css实现平行四边形
    js计算两个天数的差值
    创建vue项目的第一步——之安装vue 命令更新了
    Vue-router详解路由
    Vue-axios 在vue cli中封装
    jQuery-自己封装的弹框
    vue-上传文件
    vue-axios当只调用vue.js又需要axios请求多时
    Vant-UI移动端时间选择框
  • 原文地址:https://www.cnblogs.com/Leohh/p/7385518.html
Copyright © 2011-2022 走看看