矩阵快速幂
1013 3的幂的和
1 秒 131,072 KB 20 分 3 级题
求:3^0 + 3^1 +…+ 3^(N) mod 1000000007
输入
输入一个数N(0 <= N <= 10^9)
输出
输出:计算结果
输入样例
3
输出样例
40
用矩阵快速幂做:
递推公式:
f
(
n
)
=
1
3
∗
f
(
n
−
1
)
3
n
0
3
3
n
−
1
\begin{matrix} f(n) & = &1& 3 & *& f(n-1)\\ 3^{n} & & 0 &3&& 3^{n-1}\\ \end{matrix}
f(n)3n=1033∗f(n−1)3n−1
ac的代码:
#pragma comment(linker, "/STACK:10240000,10240000")
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
const int mod=1e9+7;
struct Mat
{
ll m[2][2];
Mat()
{
memset(m,0,sizeof(m));
}
};
Mat pul(Mat A, Mat B)
{
Mat C;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
{
C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%mod;
}
}
}
return C;
}
Mat pow(Mat A, ll n)
{
Mat B;
for(int i=0;i<2;i++)
B.m[i][i]=1;
while(n)
{
if(n&1)
B=pul(B, A);
A=pul(A,A);
n>>=1;
}
return B;
}
int main()
{
ll n;
scanf("%lld",&n);
Mat A;
A.m[0][0]=1;
A.m[0][1]=A.m[1][1]=3;
Mat B=pow(A, n);
printf("%lld\n",(B.m[0][0]+B.m[0][1])%mod);
return 0;
}
用逆元做:
A n s = 3 n + 1 − 1 2 m o d ( 1 e 9 + 7 ) = 2 模 1 e 9 + 7 的 逆 元 ∗ ( 3 n + 1 − 1 ) m o d ( 1 e 9 + 7 ) Ans = \frac{3^{n+1} -1} {2} mod(1e9+7) \\ = {2模1e9+7的逆元} *(3^{n+1} -1)mod(1e9+7) Ans=23n+1−1mod(1e9+7)=2模1e9+7的逆元∗(3n+1−1)mod(1e9+7)
2模1e9+7的逆元是500000004 ,这个怎么求可参考:博客
#include<stdio.h>
#define mod 1000000007
typedef long long ll;
ll mod_pow(ll x,ll n)
{
ll res = 1;
while(n > 0)
{
if(n & 1)
res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int main()
{
ll n, ans;
scanf("%lld", &n);
ans = (mod_pow(3, n+1) - 1) * 500000004 % mod; //求2的逆元即可.因为2 * ? = 1 (mod 1000000007) ? = 500000004
printf("%lld", ans);
return 0;
}