zoukankan      html  css  js  c++  java
  • 乘法逆元的n种解法

    Rising_Date苣佬讲解

    
    
        我们学着只争朝夕。
    
        人生苦短,
    
        道路漫长,
    
        我们走向并珍爱每一处风光,
    
        我们不停地走着,
    
        不停地走着的我们也成了一处风光。
    
    

    法一:线性递推

    #include<bits/stdc++.h>
    #define N 3000010
    #define ll long long
    #define rep(i,a,b) for(ll i=a;i<=b;++i)
    using namespace std;
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)-(c^48);c=getchar();}x=f?x:-x;}
    
    ll inv[N],n,p;//不开long long 见祖宗 
    int main()
    {
    	rd(n),rd(p) ;
    	inv[1]=1;
    	puts("1");
        rep(i,2,n)
    	{
            inv[i]=(ll)p-(p/i)*inv[p%i]%p;
    //		inv[i]=(ll)(p-(p/i))*inv[p%i]%p;这样写也可以 
    		/*我们需要保证i^-1>0所以,我们在右边 +p而且for循环要从2开始,防止改变inv[1]的值;*/
            printf("%lld
    ",inv[i]);
        }
    	return 0;
    }
    

    法*【阶乘求逆元】

    讲解

    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i)
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)-(c^48);c=getchar();}x=f?x:-x;}
    #define ll long long
    
    ll n,p;
    ll fac[3000006],ans[3000006];
    
    ll ksm(ll x,ll power)
    {
    	ll ans=1;
    	for(;power;power>>=1,(x*=x)%=p)
    		if(power&1)
    			(ans*=x)%=p;
    	return ans%p;
    } 
    
    int main()
    {
    	rd(n),rd(p);
        fac[0]=1;
        rep(i,1,n)fac[i]=(fac[i-1]*i)%p;
        ll last=ksm(fac[n],p-2);
        dwn(i,n,1)
        {
    		ll k;
            k=(last*i)%p;
            ans[i]=(last*fac[i-1])%p;
            last=k;
        }
        rep(i,1,n)
            printf("%lld
    ",ans[i]);
        return 0;
    }
    

    法2:费马小定理【会t】

    #include<bits/stdc++.h>
    #define N 3000010
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)-(c^48);c=getchar();}x=f?x:-x;}
    
    int n,p;
    
    ll ksm(ll x,ll power)
    {
    	ll ans=1;
    	for(;power;power>>=1,(x*=x)%=p)
    		if(power&1)
    			(ans*=x)%=p;
    	return ans%p;
    }
    
    int main()
    {
    	rd(n),rd(p);
    	rep(i,1,n)
            printf("%d
    ",ksm(i,p-2));
        return 0;
    }
    

    法3:解不定方程(exgcd)【会t】

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i)
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)-(c^48);c=getchar();}x=f?x:-x;}
    #define ll long long
    ll x,y,n,p;
    
    void exgcd(ll a,ll b,ll &x,ll &y) 
    {
    	if(!b)x=1,y=0;
    	else{exgcd(b,a%b,y,x);y-=a/b*x;}
    }
    
    int main()
    {
    	rd(n),rd(p);
    	rep(i,1,n)
    	{
    		exgcd(i,p,x,y);
    		printf("%lld
    ",(x%p+p)%p);
    	}
        return 0;
    }
    
  • 相关阅读:
    python自定义排序
    flex 布局
    display: table-cell; 元素上下左右居中,子元素无宽高
    transform 方法 上下左右元素居中 子元素无宽高
    flex 方法上下左右居中 子元素无宽高
    兼容-02
    兼容
    jS辨别访问浏览器判断是android还是ios系统
    选项卡
    返回顶部
  • 原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634717.html
Copyright © 2011-2022 走看看