HDU - 4990 Reading comprehension

矩阵快速幂搞一下。。f(x) = 2*f(x-1)+1,x为奇数,反之f(x) = 2f(x-1)。考虑到n比较大,因此想到矩阵快速幂优化,可构造如下矩阵,顺便测下latex能不能用。。

 凑合看吧,我实在不想改了。。矩阵显示不出来,如果你不会latex,自己去学咯。

$$

\bordermatrix{&f_{x}&f_{x-1}&g_{x}\cr

  f_{x-1}  &  3  &    1   &   0  \cr  

  f_{x-2}  &  -2 &    0    &  0  \cr

  g_{x-1} &  1   &   0    &   -1 \cr}

$$

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<list>
#include<cstring>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 3005
#define maxm 100005
#define ull unsigned long long
#define ll long long
#define hashmod 99999839
ll n,m;
struct matrix{
    ll a[3][3];
    matrix(){
        memset(a,0,sizeof(a));
    }
    void unit(){
        a[0][0] = a[1][1] = a[2][2] = 1;
    }
    void init(){
        a[0][0] = 3,a[0][1] = 1,a[1][0] = -2,a[2][0] = 1,a[2][2] = -1;
    }
    matrix operator* (const matrix& p){
        matrix ans;
        for(int i = 0;i < 3;++i){
            for(int j = 0;j < 3;++j){
                for(int k = 0;k < 3;++k){
                    ans.a[i][j] = ans.a[i][j] + a[i][k] * p.a[k][j];
                    if(ans.a[i][j] < 0) ans.a[i][j] += m;
                    if(ans.a[i][j] >= m) ans.a[i][j] %= m;
                }
            }
        }
        return ans;
    }
};
void solve(ll n){
    matrix ans,p;
    ans.unit(),p.init();
    while(n){
        if(n & 1) ans = ans * p;
        p = p * p;
        n >>= 1;
    }
    ll s = ans.a[0][0] - ans.a[2][0];
    if(s < 0) s += m;
    if(s >= m) s %= m;
    printf("%lld\n",s);
}
int main(){
    freopen("a.in","r",stdin);
    freopen("b.out","w",stdout);
    while(~scanf("%lld%lld",&n,&m)){
        solve(n-1);
    }
    return 0;
}

 

posted @ 2018-08-24 10:12  zhuiyicc  阅读(107)  评论(0编辑  收藏  举报