• HDU 3306 Another kind of Fibonacci 矩阵快速幂


    题意:给你 a[n] = x*a[n-1] + y*a[n-2]  ,求 a[n]^2 的前 n项和 S(n)

    解题思路:还是没有能理解矩阵快速幂的精髓,每做一题就要多学一点,这个题目并没有直接要到  a[n]  a[n-1] 这写东西

    而是直接找其中的关联性的东西

    a[n]^2 = xx * a[n-1]^2 + yy a[n-2]^2 + 2 * x * y *a[n-1] * a[n-2];

    a[n]*a[n-1] = a[n-1]^2 * x + y *a[n-1]*a[n-2];

    找到这些公式,我们就能够快速求出矩阵快速幂了

    解题代码:

      1 // File Name: temp.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年09月17日 星期三 11时35分45秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 #define m 10007
     26 using namespace std;
     27 LL  n,x,y ,k ; 
     28 struct Matrix
     29 {
     30    LL   mat[4][4];
     31    void clear()
     32    {
     33       memset(mat,0,sizeof(mat));
     34    }
     35    void output()
     36    {
     37      for(int i = 0  ;i < n ;i ++)
     38      {
     39        for(int j = 0 ;j < n ;j ++)
     40            printf("%lld ",mat[i][j]);
     41      printf("
    ");
     42      }
     43    }
     44    void init()
     45    {
     46       clear();
     47       mat[0][0] = (x*x ) %m ; 
     48       mat[0][1] =  y * y  %m ;
     49       mat[0][2] =  2*x* y%m;
     50       mat[1][0] = 1;
     51       mat[2][0] = x;
     52       mat[2][2] = y;
     53       mat[3][0] = 1;
     54       mat[3][3] = 1;
     55       n = 4 ;
     56    }
     57    Matrix operator *(const Matrix &b) const
     58    {
     59        Matrix ret;
     60        ret.clear();
     61        for(int i = 0 ;i < n ;i ++)
     62            for(int j = 0;j < n;j ++)
     63            {
     64                for(int s = 0 ;s < n ;s ++)
     65                {
     66                  ret.mat[i][j] =(ret.mat[i][j] + mat[i][s] * b.mat[s][j] %m ) %m  ; // 第I 行  第J  列        
     67                }
     68            }
     69        return ret;
     70    }
     71 };
     72 Matrix Pow( Matrix a ,LL t )
     73 {
     74   Matrix ret;
     75   ret.clear();
     76   for(int i = 0 ;i < n ;i ++)
     77        ret.mat[i][i] = 1;
     78   Matrix tmp = a; 
     79   while(t)
     80   {
     81       if(t&1) ret = ret * tmp;
     82       tmp = tmp * tmp;
     83       t >>=1;
     84   }
     85   return ret;
     86 }
     87 int main(){
     88 
     89     while(scanf("%lld %lld %lld",&k,&x,&y) != EOF)
     90     {
     91        x %= m; 
     92        y %= m;
     93        Matrix a;
     94        a.init();
     95        //a.output();
     96        a = Pow(a,k);
     97        //a.output();
     98        LL ans = (a.mat[3][0]  + a.mat[3][1]  + a.mat[3][2] + a.mat[3][3] ) %m  ; 
     99        printf("%lld
    ",ans);
    100     }
    101     return 0;
    102 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    516. 最长回文子序列
    NC50493 环形石子合并
    NC16650 采药
    NC16664 合唱队形
    NC51170 石子合并
    148. 合并果子
    NC25138 子串查询
    二维数组对角线 的 规律
    如何讲一个网页转换为jpg?(图片!)
    Java两倍 犯错题
  • 原文地址:https://www.cnblogs.com/zyue/p/3980052.html
Copyright © 2020-2023  润新知