數論學習

歐拉函數篩法

歐拉函數:phi(i)為1到i之間與i互質的數的個數

 

 1 int prime[N],phi[N],isprime[N];
 2 void getpri()
 3 {
 4     int cnt=0;
 5     phi[1]=1;
 6     memset(isprime,0,sizeof(isprime));
 7     for(int i=2;i<N;++i)
 8     {
 9         if(!isprime[i])
10         {
11             prime[cnt++]=i;
12             isprime[i]=i;//質數條件isprime[i]==i
13             phi[i]=i-1;//質數的phi=i-1
14         }
15         for(int j=0;j<cnt&&i*prime[j]<N;++j)
16         {
17             isprime[i*prime[j]]=prime[j];
18             if(prime[j]>=isprime[i])//保證只有i的最小質因數的把i篩掉
19             {
20                 phi[i*prime[j]]=phi[i]*prime[j];//i與prime[j]不互質時
21                 break;
22             }
23             else
24                 phi[i*prime[j]]=phi[i]*(prime[j]-1);//i與prime[j]互質時
25         }
26     }
27 }

 

擴展Euclid

 1 ll exgcd(ll a,ll b,ll &x,ll &y)
 2 {
 3     if(b==0)
 4     {
 5         x=1;
 6         y=0;
 7         return a;
 8     }
 9     else
10     {
11         ll ret=exgcd(b,a%b,y,x);
12         y-=a/b*x;
13         return ret;
14     }
15 }

 

逆元求法

  一、Fermat 小定理

    若模數為素數p,整數$x$的乘法逆元為 $x^{p-2}$,直接用快速冪求得

  二、擴展Euclid

    若模數$m$不為素數,但x與m互質時,需要用EXGCD求:

1 int x,y;
2 ll t=exgcd(x,m,x,y);
3 // x 即位所求

 

  三、線性遞推求逆元

    對於同一個模數p(prime),如果需要多次使用多個數的逆元,則可線性把一定範圍的逆元求出來。

1 int inv[N];
2 inv[1]=1;
3 for(int i=1;i<p;++i)
4     inv[i]=-(p/i)*inv[p%i];

 

转载于:https://www.cnblogs.com/Lin88/p/9902177.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值