基准时间限制:1 秒 空间限制:131072 KB 分值: 20
难度:3级算法题
求:3^0 + 3^1 +...+ 3^(N) mod 1000000007
Input
输入一个数N(0 <= N <= 10^9)
Output
输出:计算结果
Input示例
3
Output示例
40
思路:列举前几个可以看出 ans= (f(n)+(f(n)-1)/2 )%MOD --f(n)=3^n
但是 除法对于取余并没有封闭性,因此要把 除法转换掉,就要用到 乘法逆元.
乘法逆元:若数 x 是 a*x%p=1 则x为 a对于p的乘法逆元,记为 a^(-1)
即 a*a^(-1) = 1 (mod p)
乘法逆元的一大应用是模意义下的除法,除法在模意义下并不是封闭的,但我们可以根据上述公式,将其转化为乘法
x/y=x/y*(y*y^(-1))=x*y^(-1) (mod p)
利用费马小定理 a^(p-1)=1 (mod p) p 为素数。
则 a^(p-1)=1 (mod p) --> a*a^(p-2)=1 (mod p)
由乘法逆元的定义a^(p-2) 即为 a 的乘法逆元。
使用快速幂计算 a^(p-2),时间复杂度为 O(loga)。
Code:
#include<iostream>
using namespace std;
typedef long long LL;
const LL MOD=1000000007;
int n;
int pow(int n,LL p){
LL ans=1,num=n;
while(p){
if(p&1) ans=ans*num%MOD;
num=num*num%MOD;
p>>=1;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n){
LL a=3,ans=1;
while(n>0){
if(n&1) ans=ans*a%MOD;
a=a*a%MOD;
n>>=1;
}
LL bi=pow(2,MOD-2);
ans=(3*ans+2*MOD-1)*bi%MOD;
cout<<ans<<endl;
}
return 0;
}