UVaLive 7361 Immortal Porpoises (矩阵快速幂)

题意:求Fibonacci的第 n 项。

析:矩阵快速幂,如果不懂请看http://www.cnblogs.com/dwtfukgv/articles/5595078.html

是不是很好懂呢。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <stack>
using namespace std;

typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 10 + 5;
const int mod = 1e9;
const char *mark = "+-*";
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
int n, m;
inline bool is_in(int r, int c){
    return r >= 0 && r < n && c >= 0 && c < m;
}
struct Matrx{
    LL x[3][3];
    void init(){
        memset(x, 0, sizeof(x));
    }
};

Matrx mul(const Matrx &lhs, const Matrx &rhs){
    Matrx c;
    c.init();
    for(int i = 0; i < 2; ++i){
        for(int j = 0; j < 2; ++j){
            for(int k = 0; k < 2; ++k){
                c.x[i][j] += lhs.x[i][k] * rhs.x[k][j];
                c.x[i][j] %= mod;
            }
        }
    }
    return c;
}

Matrx fast_pow(Matrx x, LL b){
    Matrx ans, k = x;
    ans.x[0][0] = ans.x[10][0] = ans.x[0][1] = 1;
    ans.x[1][1] = 0;

    while(b){
        if(b & 1){
            ans = mul(ans, k);
        }
        b >>= 1;
        k = mul(k, k);
    }

    return ans;
}

int main(){
    Matrx mx;
    mx.x[0][0] = mx.x[0][1] = mx.x[1][0] = 1;
    mx.x[1][1] = 0;
    Matrx nx;
    nx.init();
    nx.x[0][0] = 1;  nx.x[0][1] = 0;
    int T;  cin >> T;
    while(T--){
        LL n;
        scanf("%d %lld", &m, &n);
        printf("%d ", m);
        if(1LL == n){  printf("1
");  continue; }
        else if(2LL == n){  printf("1
"); continue; }
        Matrx ans = fast_pow(mx, n-2);
        ans = mul(ans, nx);
        printf("%lld
", ans.x[0][0]);
    }
    return 0;
}

  

这也是运用矩阵快速幂的思想写的。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <stack>
using namespace std;

typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 100 + 5;
const int mod = 1e9;
const char *mark = "+-*";
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
int n, m;
inline bool is_in(int r, int c){
    return r >= 0 && r < n && c >= 0 && c < m;
}
map<LL, LL> ans;

LL dfs(LL n){
    if(ans.count(n))  return ans[n];
    LL k = n/2LL;
    if(n % 2 == 0)  return ans[n] = (dfs(k) * dfs(k) + dfs(k-1)* dfs(k-1)) % mod;
    else return ans[n] = (dfs(k) * dfs(k+1) + dfs(k-1) * dfs(k)) % mod;
}

int main(){
    ans[0] = ans[1] = 1;
    int T;   cin >> T;
    while(T--){
        LL x;
        scanf("%d %lld", &m, &x);
        printf("%d %lld
", m, dfs(x-1));
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/dwtfukgv/p/5774245.html