3的幂的和
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注
求:30+31+...+3Nmod100000000730+31+...+3Nmod1000000007
Input
输入一个数N(0<=N<=109)N(0<=N<=109)
Output
输出:计算结果
Input示例
3
Output示例
40
这道题看起来像是让计算等比数列求和的
ans=3N+1−12ans=3N+1−12
但是这样做的话我是直接错了,后来想到用逆元的方法来计算这一道题ans=(3N+1−1)∗xans=(3N+1−1)∗x
其中2x≡1mod10000000072x≡1mod1000000007
所以求出xx就能解决这个问题,xx可以利用费马小定理求出
x=21000000005mod1000000007x=21000000005mod1000000007
或者用拓展欧几里得算法求,即解方程2x+1000000007y=12x+1000000007y=1
code
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long long ll;
ll pow_mod(ll a,ll b,ll c)
{
ll ans=1;
a%=c;
while(b)
{
if(b&1) ans=ans*a%c;
a=a*a%c;
b>>=1;
}
return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
ll r=exgcd(b,a%b,y,x);
y-=a/b*x;
return r;
}
ll inv(ll a,ll mod)
{
ll x,y;
ll d=exgcd(a,mod,x,y);
if(d==1) return (x%mod+mod)%mod;
return -1;
}
int main()
{
ll n;
while(~scanf("%lld",&n))
{
ll ans=(pow_mod(3,n+1,1000000007)-1)*inv(2,1000000007)%1000000007;
printf("%lld\n",ans%1000000007);
}
return 0;
}
本文介绍了一种高效计算3的幂次和的算法,并通过使用逆元和费马小定理来解决大数模运算的问题。文章提供了一个C++实现示例,包括快速幂、扩展欧几里得算法及逆元的计算。
812

被折叠的 条评论
为什么被折叠?



