数论基础( 一 )

一·、
快速幂:
例如:a^b
3 ^ 23 =3^ ( 2^0 + 2^1 + 2^2 + 2*4 )
个人理解:
指数23的二进制数: 1 0 1 1 1
当指数对应二进制位为 0 不执行运算
当指数对应二进制位执行运算
注意快速幂爆 int 的问题

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

long long Qmult(long long a,long long b,long long c) 
{//快速幂,a为底,b为指数,c为取余的数 
	long long ans=1;
	while(b!=0)
	{
		if(b&1)  //对应指数的二进制位为1时,执行运算;对应二进制位为0时,不执行 
		    ans=ans*a%c;
		a=a*a%c;     //更新底数,实现累乘 
		b>>=1;   //丢掉指数的二进制的低位 
	}
	return ans;    //返回结果 
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int a,n,b,result;
		cin>>a>>n>>b;
		result=Qmult(a,n,b);
		cout<<result<<endl;
	}
} 

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

long long Q_mull(long long A,long long B,long long mod)  //快速乘 
{
	long long ans=0;
	long long res=A;
	while(B)
	{
		if(B&1)
		    ans=(res+ans)%mod;
		res=(res+res)%mod;
		B>>=1;
	}
	return ans;
}

long long Qmult(long long a,long long b,long long c) //快速幂 
{
	long long ans=1;
	while(b)
	{
		if(b&1)
		    ans=Q_mull(ans,a,c);
		a=Q_mull(a,a,c);
		b>>=1;   
	}
	return ans;
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		long long a,b,p,result;
		cin>>a>>b>>p;
		result=Qmult(a,b,p);
		cout<<result<<endl;
	}
	return 0;
}

快速乘法:
当两个数相称可能超过long long 范围的时候用,因为在加法运算的时候不会超,而且可以直接取模,这样就会保证数据超不了了。

#include<iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long LL;

LL fast_multi(LL m, LL n, LL mod)//快速乘法 
{
    LL ans = 0;//注意初始化是0,不是1 
    while (n)
    {
        if (n & 1)
            ans += m;
        m = (m + m) % mod;//和快速幂一样,只不过这里是加 
        m %= mod;//取模,不要超出范围 
        ans %= mod;
        n >>= 1;
    }
    return ans;
}
LL fast_pow(LL a, LL n, LL mod)//快速幂 
{
    LL ans = 1;
    while (n)
    {
        if (n & 1)
            ans = fast_multi(ans, a, mod);//不能直接乘 
        a = fast_multi(a, a, mod);
        ans %= mod;
        a %= mod;
        n >>= 1;
    }
    return ans;
}

int main()
{
    LL n, p;
    while (~scanf("%I64d %I64d", &n, &p))
    {
        if (n == 1)//特判一下 
        {
            printf("%I64d\n", 1 % p);
            continue;
        }
        printf("%I64d\n", (fast_pow(2, n, p) - 2 + p) % p);//这一步注意,不要为负数 
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43517282/article/details/89528232