快速幂法+逆元法(51Nod 1013)

点击这里题目:3的幂的和

           小白快速了解快速幂法和逆元法以及使用

我之前没学过快速幂法和逆元法,写过这题才知道。新手上路慢慢来!我来说下我的理解。

      快速幂法:我们知道求 a^b%N,当b很大的时候需要经过很多运算,快速幂让计算时间大大减少。我们把b转化为多个2的幂次方,首先我们需要知道一个数取模的运算:

          a*b%N=(a%N)*(b%N)     (b+a)%N=b%N+a%N.......除了除法不能直接模外,其他的和普通的运算差不多

        除法不能直接取模需要用逆元法!!!

       如:b=13:13=1101(2),,所以b=2^0+2^2+2^3;

      本来需要计算13次现在只需要计算3次就能算出答案:下面是快速幂的代码:

long long q_power(long long  a,long long b)//a^b 记得%N
{
	long long ans=1;
	while(b)
	{
		if(b&1)//b的二进制的最后一位是1
		    {
                ans=ans*a%N;
            }
		a=a*a%N;//依次求次方,但是不能超过模
		b>>=1;//把b的二进制的往前移动,去掉已经计算过的那位数
	}
	return ans;
}

    每次记得取模(看情况而定取不取模,这题需要取) 

PS:这种方法N也就是要模的数必须是质数!!!,这很重要。

接下就是逆元法了,解决除法取模的情况,应用逆元法把除法变成乘法:

    首先你要知道费马小定理:

          1.a和N的最大公约数是1,gcd(a,N)=1;//N就是我们需要模的数

          2.a^(N-1)%N=1;//费马小定理,自行百度,我只知道用。

          3.简单的变形:

                   a^(N-1)%N=1

                   a^(N-2)*a%N=1

                  a^(N-2)%n=1/a

          所以我们可以把除法变成乘法:     1/a  =   a^(N-2)%N

    知道这些我们就可以去AC了

#include<stdio.h>
#define N 1000000007

/**
1.快速幂法 
2.逆元法》》把除数的模变成可以模的 
*/
long long q_power(long long  a,long long b)//a^b 记得%N
{
	long long ans=1;
	while(b)
	{
		if(b&1)//b的二进制的最后一位是1
		    {
                ans=ans*a%N;
            }
		a=a*a%N;//依次求次方,但是不能超过模
		b>>=1;//把b的二进制的往前移动,去掉已经计算过的那位数
	}
	return ans;
}
int main()
{
	long long m,n;
	scanf("%lld",&n);
//* a1*(q^(n+1)-1)/2  等比数列公式,然后把2进行逆元*/ 
	m=(q_power(3,n+1)-1);
	n=q_power(2,N-2);
	printf("%lld\n",(m*n)%N);
	return 0;
}

用拓展欧几里得求逆元的方法:拓展欧几里得求逆元

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值