51 nod 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

思路为快速幂加逆元,至于为什么要求逆元:

首先说明一个事实,你直接算出来一个数的结果直接对p取模,结果一定是对的。
但如果我们要通过一个前面取过模的式子递推出其他要取模的式子,而递推式里又存在除法
那么一个很尴尬的事情出现了,假如a[i-1]=100%31=7 a[i]=(a[i-1]/2)%31
a[i]=50%31=19 ,但我们现在只知道a[i-1]=7,如何利用a[i-1]未取模之前的值100计算出a[i]=19呢?显然用a[i]=(7/2)%31=3是不对的。

逆元的求法:

若对于数字A,C 存在X,使A * X = 1 (mod C) ,那么称X为 A 对C的乘法逆元。
逆元的作用?
12 / 4 mod 7 = ? , 很显然结果是3
我们现在对于数对 (4,7), 可以知道 X = 2是 4 对7的乘法逆元即2*4=1(mod 7)
那么我们有(12 / 4) * (4 * 2 ) = (?) * (1) (mod 7)
除法被完美地转化为了乘法
理论依据:
F / A mod C = ?
如果存在 A*X = 1 (mod C)
那么2边同时乘起来,得到 F * X = ? (mod C)
成立条件
(1) 模方程 A * X = 1(mod C) 存在解
(2) A | F (F % A == 0)


在这道题里边,计算前n项和的函数计算出的结果是对目标值取模后的值(不取模的话long long也储存不下来),所以用取模后的值去除以2就出现错误了(因为我们要的是未取模之前的值除以2的结果),这时我们利用逆元法把除法转化为乘法就不会出错了。

#include <bits/stdc++.h>
const int  mod=1000000007;
using namespace std;
long long fun(int m,int n)
{
	long long sum=1,res=m;
	while(n)
	{
		if(n%2==1)
	    sum=sum*res%mod;
	    res=res*res%mod;
	    n/=2;
	}
	return sum; 
}
int main()
{
	int n;
	cin>>n;
	n++;                                  //Sn=(a1-an*q)/(1-q)=(an*q-1)/2;
	long long ans=((fun(3,n)-1)*500000004)%mod;       //long long ans=((fun(3,n)-1)/2)%mod显然会出错;
	cout<<ans<<endl;
	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值