数论学习笔记(day3)

1.快速幂,利用幂运算的性质,快速计算一个数的n次方(mod m)

int quickpow(int a,int b,int c)
   {
      int ans=1;a=a%c;
      while(b>0)
         {if(b%2==1)ans=(ans*a)%c;
          b=b/2;a=a*a%c;}return ans;             
   }

模板题:
在这里插入图片描述

#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int b,p,k;
int quickpow(int,int,int);
int main()
   {
      cin>>b>>p>>k;
      cout<<b<<"^"<<p<<" mod "<<k<<"="<<quickpow(b,p,k);  
      return 0;  
   }
int quickpow(int a,int b,int c)
   {
      int ans=1;a=a%c;
      while(b>0)
         {if(b%2==1)ans=(ans*a)%c;
          b=b/2;a=a*a%c;}return ans;             
   }

2.快速乘
发现如果要算两个1e18数相乘再mod一个1e18的数如ab%p,如果直接相乘,很容易发现有可能直接爆long long的范围,解决方法也很好想出来,就是利用类似快速幂的方法,把两个乘数的因子分解出来,一个一个乘,再利用模运算的性质将范围控制在long long 的范围内,那么时间复杂度就是logn这样就有可能被卡时,那么此时就可以用long double的性质(保留18位舍弃低位)先保存ab/p的除数,最后的取模后的结果就是ab再减掉刚刚除数p
快速乘板子:

inline long long multi(long long x,long long y,long long mod)
{
long long tmp=(x*y-(long long)((long double)x/mod*y+1.0e-8)*mod);
return tmp<0 ? tmp+mod : tmp;
}
--------------------- 
代码来源
作者:Coder_YX 
原文:https://blog.csdn.net/qq_34731703/article/details/66478286 
--------------------

3.费马小定理
如果p是质数并且gcd(a,p)=1那么有a的p-1次方在mod p时和1同余
奇淫巧技:米勒罗宾测试
如果p是质数那么上述公式成立,反过来,这个式子成立p不一定成立。但是如果这个式子不成立这个p一定是和数,那么就会给我们提供一种快速检测一个数的素性的方法,先随机一个a带入费马小定理,如果不成立,那么一定是和数,如果成立,他有1/2的概率是质数,当他通过了足够多的测试之后,我们有足够的把握确定这个数是一个质数。
ps:有几个和数可以通过米勒罗宾测试,但是概率极小
代码:

bool check(long long a,long long n,long long x,long long t)
{
    long long ret=quickpow(a,x,n);
    long long last=ret;
    for(int i=1;i<=t;i++)
    {
        ret=quickmu(ret,ret,n);
        if(ret==1&&last!=1&&last!=n-1) return 1;
        last=ret;
    }
    if(ret!=1) return 1;
    return 0;
}
bool Robin_Miller(long long n)
{
    if(n<2)return 0;
    if(n==2)return 1;
    if((n&1)==0) return 0;
    long long x=n-1;
    long long t=0;
    while((x&1)==0){x>>=1;t++;}
    for(int i=0;i<S;i++)
    {
        long long a=rand()%(n-1)+1;
        if(check(a,n,x,t))
            return false;
    }
    return true;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值