浅谈数论

逆元

  • 逆元是一个非常牛逼的东西。求法很多,又很实用。
  • 它可以分为乘法逆元和加法逆元:
  1. 乘法逆元:如果ab==1(mod p)则我们称b是a关于p的(乘法)逆元;

  2. 加法逆元:如果a+b=0则我们称b是a的(加法)逆元。

  • a^-1==b(mod p)-> ab==1(mod p)

  • 条件:(a,p)=1;

  • 整数a对模数p之模逆元存在的充分必要条件是a和p互素,若此模逆元存在,在模数p下的除法可以用和对应模逆元的乘法来达成,此概念和实数除法的概念相同。

    模意义下的逆元就好比实数运算中的倒数,模意义下除以一个数就相当于乘上这个数的逆元,就可以实现模意义下的除法啦!

  • 线性求逆元

 

#define ll long long
......
const int p=1e9+7;
int fac[N],inv[N];
ll qpow(ll a,ll b)
{
    ll base=a,ret=1;
    while(b)
    {
        if(b&1)ret=(ret*base)%p;
        base=base*base%p;
        b>>=1;
    }
    return ret;
}
void gotinv()
{
    fac[0]=1;
    for(int i=1;i<=N;i++)fac[i]=fac[i-1]*i%p;
    inv[N]=qpow(fac[N],p-2)%p;
    for(int i=N;i>=1;i--)inv[i-1]=inv[i]*i%p;
}
......
int main()
{
    gotinv();
    ......
}
fac&inv

 


 费马小定理

  • 条件:gcd(a,p)=1;

  • a^(p-1)==1(mod p),这是定理精髓,由它我们可以推出好多玄妙的结论。

  • 时间复杂度O(log p)
  • 这里给出证明:
    • 因为{0,1,2,...,(p-1)}为p的完全剩余系,且gcd(a,p)=1,
    • 所以a对p的完全剩余系无影响
    • 所以{0*a,1*a,...,(p-1)*a}也为p的完全剩余系
    • 所以{0*a,1*a,...,(p-1)*a}={0,a,2a,...,(p-1)a}(mod p)等价于{0,1,2,...,(p-1)}(mod p)即a*2a*3a*...*(p-1)a=1*2*3*...*(p-1)(mod p)
    • 整理一下:(1*2*...*(p-1))*a^(p-1)=(1*2*3*...*(p-1))(mod p)
    • 然后我们会发现这个式子多优美。
    • a^(p-1)==1(mod p)
  • a^(p-1)==1(mod p)可得:

  1. a^(p-2)==a^-1(mod p)咋一看发现这个式子貌似是乘法逆元,所以说我们多了一种求逆元的方法qaq;
  • 这里千万注意gcd(a,p)=1


 

欧拉函数

  • phi(n)我们将其定义为n的完全剩余系中与n互质的数的个数
  • 我们现将求法说一下(名字是作者瞎起的)
  1. 分解质因数法:我们先求出n的质因数p1~pk,则phi(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pk)即可,相信正确性是有保证的
  2. 欧拉筛法:
    ll  pri[10000002],top,phi[10000002],sum[10000002];
    bool pd[10000002];
    void prime_shaker()
    {
        phi[1]=1;
        for(ll i=2;i<=n;i++)
        {
            if(!pd[i])pri[++top]=i,phi[i]=i-1;
            for(ll j=1;j<=top&&pri[j]*i<=n;j++)
            {
                pd[i*pri[j]]=true;
                if(i%pri[j]==0)
                {
                    phi[i*pri[j]]=phi[i]*pri[j];
                    break;
                }
                else phi[i*pri[j]]=phi[i]*phi[pri[j]];
            }
        }
        for(int i=1;i<=n;i++)sum[i]=sum[i-1]+phi[i];
    }
    Prime_shaker
  3. 暴力QAQ......

欧拉函数性质

  • phi(a*b)=phi(a)*phi(b)

  • 任意质数p使得phi(p)=p-1
  • 如果gcd(a,n)=1 则 (n-a,n)=1
  • n的完全剩余系中所有与n不互质的数的和sum,满足sum=phi(n)*(n/2)
  • 如果质数n=p^k(其中p为质数)则phi(n)=p^k-p^(k-1)
  • n等于n所有约数的phi的和

欧拉定理

  • if(a,p)=1,a^n=a^(n mod phi(p))modp
    因为(a,p)=1
    所以x1*x2*...*(xphi(p))==(a*x1)*......*(a*xphi(p))(mod p)

    令X=x1*x2*....*xphi(p)
    可得X==X*a^phi(p)(mod p)即a^phi(p)==1(mod p)

这里引入欧拉筛法

inline void prime_shaker(int n)
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!pd[i])prime[++top]=i,phi[i]=i-1;
        for(int j=1;j<top&&1ll*prime[j]*i<=n;j++)
        {
            pd[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]]
        }
    }
}
prime_shaker

欧拉是个伟人!


 

中国剩余定理(Crt)

  •  crt是用来解同余方程的大法
  • x==a1(mod m1)
  • x==a2(mod m2)
  • ......
  • x==ak(mod mk)
  • 解如上方程求x。
  • 令M=m1*m2*m3*...*mk,Mi=M/mi;
  • 所以x=(a1*M1*inv(M1))+...+(ak*Mk*inv(Mk));

扩展中国剩余定理(Excrt)

补:扩展欧几里得exgcd即快速求出ax+by=gcd(a,b)的一组解x,y:

C++:

void exgcd(ll a, ll b, ll& x, ll& y, ll& c)
{
    if(!b) {y = 0; x = 1; c = a; return;}
    exgcd(b, a % b, y, x); y -= a / b * x;
}
Exgcd Code
  • 假设我们都会了扩展欧几里得,那么我们用它来推一下扩展中国剩余定理。
  • 其实扩展crt特别简单...假设你搞出了前k组的一个最小正整数解x,想推出前k+1个方程的解令M=m1*m2*m3*...*mk,Mi=M/mi,显然对于任意t,x+t*M都是满足的.
  • 那么对于新的一组方程x==a.k+1(mod m.k+1)我们要找的是令x+t*M==a.k+1(mod m.k+1)最小的t, 即t*M+(m.k+1)*p=a.k+1-x,可以轻松的利用exgcd求出最小解,若某时某刻exgcd无解,则原模线性方程组无解。

代码背下来即可:

typedef long long LL;
LL calc()
{
    LL M=m[1],x=a[1];///第一组的解就是a[1],此时M之积为m[1]
    for(int i=2;i<=n;i++)
    {
        LL g=gcd(M,m[i]),t=((a[i]%m[i]-x%m[i])%m[i]+m[i])%m[i];
        if(t%g!=0) return -1;//判断exgcd是否有解
        LL xx,y;
        exgcd(M,m[i],xx,y);
        xx=mul(xx,t/g,m[i]/g);//快速乘,防止爆long long
        x=xx*M+x;
        M=M*(m[i]/g);
        x=(x%M+M)%M;
    }
    return x%M;
}
calc Code

虽然说mlkit打了这一篇博客,但mlkit那令人发指的数学水平仍然无奈。

那一次又一次的希冀在无穷无尽的失败前跌的粉身碎骨

无穷无尽的期待在绝望面前撞得头破血流qaq

Thanks

posted @ 2019-07-28 12:21  milkitblogcn  阅读(279)  评论(0编辑  收藏  举报