51nod-1013 3的幂的和(乘法逆元)

1013 3的幂的和 
基准时间限制: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
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<


你可能感兴趣的:(算法,51Nod,数论)