zoukankan      html  css  js  c++  java
  • 乘法逆元的线性筛法

    目录

    目录地址

    上一篇

    下一篇


    线性求逆元题型

    对于已知模数 (m) ,求出在模 (m) 意义下, (1)~(n) 的逆元 ( (nleq m-1)

    (n) 较大,只支持 (O(n)) 复杂度的算法

    (一般保证 (m) 是质数,否则有的数不存在逆元)


    线性算法 (O(n))

    由递推的方法 (O(n))

    考虑模 (m) 意义下 (1^{-1}equiv 1(mod m))

    考虑求 (n) 的逆元,可知 (m=lfloor{mover n} floorcdot n+(mmod n))

    (a=m/n,b=m\%n)(m=an+b,0leq b<n)

    因此 (an+bequiv 0(mod m))

    方程两边乘上 (n^{-1}) 得到

    (a+bcdot n^{-1}equiv 0(mod m))

    (n^{-1}equiv -acdot b^{-1}(mod m))

    (n^{-1}equiv -lfloor{mover n} floorcdot (mmod n)^{-1}(mod m))

    inv[1]=1;
    for(int i=2;i<=n;i++){
        inv[i]=m-m/n*inv[m%n]%m;
    }
    

    线性筛法 (O(n))

    利用线性筛的性质,以及逆元在取模意义下的积性,可以很快写出线性筛的方法:

    inv[1]=1;
    for(int i=2;i<=n;i++){
        if(fc[i]==0){
            fc[i]=i;
            prime[cntprime++]=i;
            inv[i]=fpow(i,m-2);
        }
        for(int j=0;j<cntprime&&prime[j]<=fc[i];j++){
            inv[i*prime[j] ]=inv[i]*inv[ prime[j] ];
        }
    }
    

    因为质数的个数大约是 (nover ln n) 个,快速幂的复杂度 (O(log m))(nleq m-1) ,因此质数部分的复杂度为 (O(n))

    而合数的个数大约是 ((n-{nover ln n})) 它们是线性的,因此复杂度为 (O(n))

    最终得出总复杂度为 (O(n))


    阶乘法 (O(n))

    考虑到我们可以 (O(n)) 内求出 (forall ileq n,i!)

    而我们可以花费 (O(log m)) 的时间求出 (n!^{-1}) ,由于 (nleq m-1) ,复杂度也可以认为是 (O(n))

    再利用公式: (i!^{-1}equiv (i+1)!^{-1}cdot (i+1)(mod m),i^{-1}equiv i!^{-1}cdot (i-1)!(mod m))

    得出结论:

    fac[0]=1;
    for(int i=1;i<=n;i++){
        fac[i]=fac[i-1]*i%m;
    }
    invf[n]=fpow(fac[n],m-2);
    for(int i=n-1;i>=0;i--){
        invf[i]=invf[i+1]*(i+1)%m;
    }
    for(int i=1;i<=n;i++){
        inv[i]=fac[i]*invf[i-1]%m;
    }
    

    总复杂度 (O(n))

  • 相关阅读:
    使用CuteFTP登陆FTP(servU)服务器后无法LIST目录和文件的解决方法
    delphi技巧集锦之一
    delphi技巧集锦之二
    关于varchar(max), nvarchar(max)和varbinary(max)
    别告诉我你会用WORD
    Showmodal与show的区别
    SET ANSI_NULLS ON的用法
    {右键我的电脑无法打开计算机管理}解决方法
    Word常用技巧
    Excel 使用技巧集锦——163种技巧
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/12400762.html
Copyright © 2011-2022 走看看