51Nod 1013 3的幂的和
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1013
首先得考虑到时间复杂度问题,由于题目中(0 <= N <= 10^9),用 for来累加求和是不现实的。
通过观察我们可以发现,在 3^0 + 3^1 +...+ 3^(N) mod 1000000007 中 存在等比数列,通过化简可以得到
这样就比较容易求解了,首先通过快速取幂求得 ,然后我们把令
再由推论:(a/b) mod m = (a/b)*1 mod m = (a/b)*b*c mod m=a* c(mod m); 即a/b的模等于a*b的逆元的模,求解。
代码如下:
#include <bits/stdc++.h>
typedef long long ll;
const ll mod = 1000000007;
using namespace std;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) // 推理, 终止条件1
{
x = 1;
y = 0;
return a;
}
ll r = exgcd(b, a%b, x, y);
ll t = y;
y = x - (a/b) * y;
x = t;
return r; //最大公约数
}
ll inv (ll a, ll mod) {
ll x, y;
exgcd(a, mod, x, y);
return (x + mod) % mod;
}
ll quick(ll a, ll b, ll c)
{
long ans = 1; // 记录结果
a = a % c; // 预处理,使得a处于c的数据范围之下
while (b != 0)
{
if (b & 1) ans = (ans * a) % c; // 如果b的二进制位不是0,那么我们的结果是要参与运算的
b >>= 1; // 二进制的移位操作,相当于每次除以2,用二进制看,就是我们不断遍历b的二进制位
a = (a * a) % c; // 不断的加倍
}
return ans;
}
int main(void)
{
ll n;
cin >> n;
int sum = ((quick(3, n+1, mod) - 1) * inv(2, mod))% mod;
cout << sum << endl;
return 0;
}