zoukankan      html  css  js  c++  java
  • [洛谷P3811]【模板】乘法逆元

    P3811 【模板】乘法逆元

    题意

    求1-n所有整数在模p意义下的逆元。

    分析

    逆元

    如果x满足(ax=1(\%p))(其中a p是给定的数)那么称(x)是在(%p)意义下(a)的逆元

    A 拓展欧几里得算法

    [ax=1(\%p) ]

    转换一下也就是

    [ax+py=1 ]

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int extgcd(int a,int b,int&x,int&y){
    	if(b==0){
    		x=1;
    		y=0;
    		return a;
    	}
    	int g=extgcd(b,a%b,y,x);
    	y-=a/b*x;
    	return g;
    }
    int main(){
    	int a,b,x,y;
    	cin>>a>>b;
    	for(int i=1;i<=a;i++){
    		extgcd(i,b,x,y);
    		cout<<(x%b+b)%b<<endl;
    	}
    }
    

    得分:48。TLE

    B 费马小定理

    当p是质数时:

    [a^{p-1}≡1(\%p) ]

    将其变形一下即得

    [a*a^{p-2}≡1(\%p) ]

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll qpow(ll a,ll b,ll p){
    	ll ans=1;
    	while(b){
    		if(b%2){
    			ans*=a;
    			ans%=p;
    		}
    		a*=a;
    		a%=p;
    		b>>=1;
    	}
    	return ans%p;
    }
    int main(){
    	int n,p;
    	cin>>n>>p;
    	for(int i=1;i<=n;i++){
    		cout<<(qpow(i,p-2,p)%p+p)%p<<endl;
    	}
    }
    

    得分:48。TLE

    B' 欧拉定理

    费马小定理只是欧拉定理的特殊情况。欧拉定理:

    [a^{phi(p)}=1(\%p) ]

    也就是说(a^{phi(p)-1})(a)(\%p)意义下的逆元。
    其中(phi)是欧拉函数:小于n的正整数中与n互质的数的数目。
    通式:(phi(n)=nPi_{i=1}^{n}left(1-frac{1}{p_i} ight))
    递推性质:

    1. (phi(p)=p-1) (p是质数)
    2. (phi(ab)=phi(b)phi(b)) (a,b互质)
    3. (phi(ip)=pphi(i)) (i是p的倍数)
      所以可以用类似线性筛的方法求出欧拉函数表。
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll qpow(ll a,ll b,ll p){
    	ll ans=1;
    	while(b){
    		if(b%2){
    			ans*=a;
    			ans%=p;
    		}
    		a*=a;
    		a%=p;
    		b>>=1;
    	}
    	return ans%p;
    }
    ll n,p;
    ll phi[20000529],prime[2000052],ps;
    bool mark[2000052];
    void calc(){
    	phi[1]=1;
    	for(int i=2;i<=p;i++){
    		if(!mark[i]){
    			prime[++ps]=i;
    			phi[i]=i-1;
    		}
    		for(int j=1;j<=ps;j++){
    			if(i*prime[j]>p)break;
    			mark[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]*(prime[j]-1);
    			}
    		}
    	}
    }
    int main(){
    	cin>>n>>p;
    	calc();
    	for(int i=1;i<=n;i++){
    		cout<<(qpow(i,phi[p]-1,p)%p+p)%p<<endl;
    	}
    }
    

    得分:32。TLE

    C 神奇的递推式(正解)

    [p=ka+r ]

    然后放到(\%p)意义下

    [ka+r=0(\%p) ]

    两边同时乘以(a^{-1}r^{-1})

    [kr^{-1}+a^{-1}=0(\%p) ]

    所以

    [a^{-1}=-kr^{-1}=-left[frac{p}{a} ight]*(p\%a)^{-1} ]

    转换成代码就是

    inv[a]=-(p/a)*inv[p%a];
    

    正解代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n,p;
    int inv[3000000];
    int main(){
    	scanf("%d%d",&n,&p);
    	inv[1]=1;
    	printf("1
    ");
    	for(int i=2;i<=n;i++){
    		inv[i]=((-((ll)p/i)*inv[p%i])%p+p)%p;
    		printf("%d
    ",inv[i]);
    	}
    }
    
  • 相关阅读:
    FTP文件传输应用分析
    A*寻路算法
    Asp.net页面事件引发后台程序处理原理
    开发人员的基本原则(转)
    定位new表达式
    常量对象的动态分配和释放
    PostThreadMessage使用
    最美丽的数学公式
    仿函数
    CF1598EStaircases【计数】
  • 原文地址:https://www.cnblogs.com/water-lift/p/10427780.html
Copyright © 2011-2022 走看看