D - 3的幂的和 快速幂+费马小定理 或 快速幂+扩展欧几里得

求:3^0 + 3^1 +...+ 3^(N) mod 1000000007

Input

输入一个数N(0 <= N <= 10^9)

Output

输出:计算结果

Sample Input

3

Sample Output

40

费马小定理     1.mod=质数  2.a与mod互质  则a的逆元为a的p-2次方;

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL Quick_mod(LL a,LL b,LL c)    //快速幂
{
    LL ans=1;
    a=a%c;
    while(b)
    {
        if(b&1)
          ans=(ans*a)%c;
        b>>=1;
        a=(a*a)%c;
    }    
    return ans;
}                                            //以下涉及  (a/b)mod m=a*c mod m    c为b的逆元
int main()
{
    LL n;                              //输出是((3^n+1-1)/2)mod  1000000007推至((3^n+1-1)*(2的逆元))mod  1000000007
    LL mod=1e9+7;            //推至  ((3^n+1-1)mod  1000000007*{(2的逆元)mod  1000000007})mod  1000000007
    cin>>n;                              
    cout<<((Quick_mod(3,n+1,mod)-1)*Quick_mod(2,mod-2,mod))%mod<<endl;
    return 0;
}

扩展欧几里得

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const long long mod=1000000007;
ll extgcd(ll a,ll b,ll &x,ll &y)   //扩展欧几里德   记住魔板就行了
{
    if(b==0){
        x=1,y=0;
        return a;
    }
    ll d=extgcd(b,a%b,x,y);
    ll t=x;
    x=y;
    y=t-a/b*y;
    return d;

ll inv(ll a,ll mod)
{
    ll x,y;
    extgcd(a,mod,x,y);
    return (mod+x%mod)%mod;
}
long long pow_mod(long long a,long long n,long long c)   //快速幂 
{
    long long res=1;
    while(n)
    {
        if(n&1) res=res*a%c;
        a=a*a%c;
        n>>=1;
    }
    return res;
}
int main()
{
    long long n,res;
    cin>>n;
    res=((pow_mod(3,n+1,mod)-1)*inv(2,mod))%mod;
    cout<<res<<endl;
}

猜你喜欢

转载自blog.csdn.net/lbs311709000127/article/details/81191168