##逆元
乘法逆元:
有 a * x = 1 (mod c) 称 x 为 a 与 c 的乘法逆元。
理论依据:(mod 对于加减乘除都可进行分配)
f / a mod c= ? (f mod c / a mod c = ?)
如果存在 ax = 1(mod c)
那么两边同时乘起来,得到 fx = ?(mod c)
成立条件:
1 模方程 a*x= 1(mod c)存在解
2 a | f (f%a==0)
注 : 若a*x=1 (mod c) 则称 a 关于模 c 的乘法逆元为 x.当 a 与c 互素时 , x 有唯一解。如果不互素则无解。如果 c 为素数,则从1 到 c-1 的任意数都与 c 互素, 即在 1 到c-1之间都恰好有一个关于模 c 的逆元。
##快速幂
& 表示在二进制中取位
typedef long long ll;
ll mul(ll n,ll s)
{
ll res=1;
while(n) // 也可以用>>移位符号 for(; n>0; n>>=1)
{ // {
if(n%2) // if(n%2==1)
res=res*s; // res=res*s;
s=s*s; // s=s*s;
n/=2; // }
}
return res
}
##例题
3的幂的和
求:3^0 + 3^1 +…+ 3^(N) mod 1000000007
Input
输入一个数N(0 <= N <= 10^9)
Output
输出:计算结果
Sample Input
3
Sample Output
40
分析:
30+31+32+…+3n=(3^(n+1)-1) / 2
f / 2 mod c = f * x mod c
2 * x =1(mod c)
x = (c+1)/2
#include<iostream>
using namespace std;
#define mod 1000000007
long long mul(long long a,long long n)
{
long long ret=1;
while(n)
{
if(n&1)
ret=ret*a%mod;
a=a*a%mod;
n/=2;
}
//cout<<ret<<endl;
return ret;
}
int main()
{
long long n;
cin>>n;
long long ans;
ans=(mul(3,n+1)-1)*((mod+1)/2)%mod;
cout<<ans<<endl;
}