1. 程式人生 > >51nod 1013 3的冪的和(矩陣快速冪)(逆元)

51nod 1013 3的冪的和(矩陣快速冪)(逆元)

方法一:矩陣快速冪:

             \bigl(\begin{smallmatrix} & \\ 3 & 1 & \\ 0 & 1 \end{smallmatrix}\bigr)*\bigl(\begin{smallmatrix} & \\ 3 & 1 & \\ 0 & 1 \end{smallmatrix}\bigr)

 

方法二:逆元

         等比數列求和公式

        因為q=3,a1=1.所以化簡下就是 (3^n-1)*2%1e9+7

以下程式碼是矩陣快速冪的

#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstdlib>
#include<map>
using namespace std;
typedef long long ll;
ll mod=1000000007;
struct matrix
{
    ll m[3][3];
}ans,res;
matrix mul(matrix a,matrix b)
{
    matrix tmp;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
        tmp.m[i][j]=0;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
            for(int k=1;k<=2;k++)
            {
                 tmp.m[i][j]+=a.m[i][k]*b.m[k][j];
                 tmp.m[i][j]%=mod;
            }

    return tmp;

}

void quickpower(int N)
{
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
        {
            if(i==j) ans.m[i][j]=1;
            else ans.m[i][j]=0;
        }
    while(N)
    {
        if(N&1) ans=mul(ans,res);
        res=mul(res,res);
        N>>=1;
    }
}
int main()
{
   int N;
   scanf("%d",&N);
   res.m[1][1]=3;res.m[1][2]=1;
   res.m[2][1]=0;res.m[2][2]=1;
   quickpower(N+1);
   cout<<ans.m[1][2]%mod<<endl;

   return 0;
}