HDU 2256 & HDU 4565 (矩阵快速幂 + 公式推演)

来源:互联网 发布:python buffering 编辑:程序博客网 时间:2024/06/05 15:13

HDU 2256

题意:

计算(2+3)2nmod1024

思路:

f(n)=(2+3)2n=(5+26)n=An+Bn6

f(n1)=An1+Bn16

f(n)=(5+26)f(n1)

f(n)=(5An1+12Bn1)+(2An1+5Bn1)6
所以递推矩阵就是:

(52125)(An1Bn1)=(AnBn)

A1=5,B1=2.

然后套矩阵快速幂模板即可求出An,Bn.

(5+26)n=An+Bn6

(526)n=AnBn6

(5+26)n+(526)n=2An

(526)n<1

(5+26)n=2An1

所以最后答案就是2An1

代码:

/** @author FreeWifi_novicer* language : C++/C*/#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<string>#include<map>#include<set>#include<vector>#include<queue>using namespace std;#define clr( x , y ) memset(x,y,sizeof(x))#define cls( x ) memset(x,0,sizeof(x))#define mp make_pair#define pb push_backtypedef long long lint;typedef long long ll;typedef long long LL;const int mod = 1024;const int maxn = 4;struct Matrix{    int n,m;    lint a[maxn][maxn];    Matrix(int n , int m){        this->n = n;        this->m = m;        cls(a);    }    Matrix operator * (const Matrix &tmp){        Matrix res(n,tmp.m);        for(int i = 0 ; i < n ; i++){            for(int j = 0 ; j < tmp.m ; j++){                for(int k = 0 ; k < m ; k++){                    res.a[i][j] = (res.a[i][j] + (a[i][k] * tmp.a[k][j]) % mod) % mod;                }            }        }        return res;    }};void Matrix_print(Matrix x){    for(int i = 0 ; i < x.n ; i++){        for(int j = 0 ; j < x.m ; j++) cout << x.a[i][j] << ' ';        cout << endl;    }}Matrix fast_pow(Matrix x ,int n){    Matrix res(x.n,x.m);    for(int i = 0 ; i <  x.n ; i++) res.a[i][i] = 1;    while(n){        if(n&1)            res = res * x;        x = x*x;        n >>= 1;        //Matrix_print(res);        //cout << endl;    }    return res;}void solve(){    lint n;    cin >> n;    if(n == 1){        cout << 9 << endl;        return;    }    Matrix base(2,1);    Matrix fun(2,2);    base.a[0][0] = 5;    base.a[1][0] = 2;    fun.a[0][0] = 5;    fun.a[0][1] = 12;    fun.a[1][0] = 2;    fun.a[1][1] = 5;    fun = fast_pow(fun,n-1);    base = fun * base;    cout << (2*base.a[0][0] - 1) % mod << endl;}int main(){    int t ; cin >> t;    while(t--){        solve();    }    return 0;}

附送HDU 4565代码:

/** @author FreeWifi_novicer* language : C++/C*/#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<string>#include<map>#include<set>#include<vector>#include<queue>using namespace std;#define clr( x , y ) memset(x,y,sizeof(x))#define cls( x ) memset(x,0,sizeof(x))#define mp make_pair#define pb push_backtypedef long long lint;typedef long long ll;typedef long long LL;lint mod;lint n , a , b ;const int maxn = 4;struct Matrix{    int n,m;    lint a[maxn][maxn];    Matrix(int n , int m){        this->n = n;        this->m = m;        cls(a);    }    Matrix operator * (const Matrix &tmp){        Matrix res(n,tmp.m);        for(int i = 0 ; i < n ; i++){            for(int j = 0 ; j < tmp.m ; j++){                for(int k = 0 ; k < m ; k++){                    res.a[i][j] = (res.a[i][j] + (a[i][k] * tmp.a[k][j]) % mod) % mod;                }            }        }        return res;    }};void Matrix_print(Matrix x){    for(int i = 0 ; i < x.n ; i++){        for(int j = 0 ; j < x.m ; j++) cout << x.a[i][j] << ' ';        cout << endl;    }}Matrix fast_pow(Matrix x ,int n){    Matrix res(x.n,x.m);    for(int i = 0 ; i <  x.n ; i++) res.a[i][i] = 1;    while(n){        if(n&1)            res = res * x;        x = x*x;        n >>= 1;        //Matrix_print(res);        //cout << endl;    }    return res;}void solve(){    if(n == 1){        lint ans = (lint)( a + ceil( sqrt( b * 1.0 ) ) ) % mod;        cout << ans << endl;        return;    }    Matrix base(2,1);    Matrix fun(2,2);    base.a[0][0] = a % mod;    base.a[1][0] = 1;    fun.a[0][0] = a % mod;    fun.a[0][1] = b % mod;    fun.a[1][0] = 1;    fun.a[1][1] = a % mod;    fun = fast_pow(fun,n-1);    base = fun * base;    cout << (2 * base.a[0][0]) % mod << endl;}int main(){    while(cin >> a >> b >> n >> mod ){        solve();    }    return 0;}
0 0