zoukankan      html  css  js  c++  java
  • 常用数论模板

    ---恢复内容开始---

    几种乘法逆元的求法:

    这里假设mod=1e9+7

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<stack>
    #include<cstdio>
    #include<map>
    #include<set>
    #include<string>
    #include<queue>
    using namespace std;
    #define inf 0x3f3f3f3f
    #define ri register int
    typedef long long ll;
    
    inline ll gcd(ll i,ll j){
    	return j==0?i:gcd(j,i%j);
    }
    inline ll lcm(ll i,ll j){
    	return i/gcd(i,j)*j;
    }
    inline void read(int &x){
        char ch=x=0;
        while(!isdigit(ch))
            ch=getchar();
        while(isdigit(ch))
            x=x*10+ch-'0',ch=getchar();
    }
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int ivn[maxn];
    void egcd(int a,int b,int & x,int & y){//拓展欧几里得求a的逆元(为X), 
    	if(b==0){
    		x=1;
    		y=0;
    		return ;
    	}
    	egcd(b,a%b,x,y);
    	int x1=x;
    	int y1=y;
    	x=y1;
    	y=(x1-(a/b)*y1+mod)%mod;
    	return ;
    }
    int qpow(int a,int b){ //利用费马定理求a逆元 
    	int ans=1;
    	while(b){
    		if(b&1)ans=(ll)ans*a%mod;
    		a=(ll)a*a%mod;
    		b/=2;
    	}
    	return ans;
    }
    void work(){//线性求1~(mod-1)的逆元 
    	ivn[1]=1;
    	for(int i=2;i<=maxn;i++){
    		ivn[i]=(ll)(mod-mod/i)*ivn[mod%i]%mod;
    	}
    }
    int main(){
    	int ivn1,ivn2;
    	int a;
    	egcd(2,mod,ivn1,a);
    	ivn2=qpow(2,mod-2);
    	cout<<ivn1<<" "<<ivn2<<endl;
    	int n;
    	work();
    	while(~scanf("%d",&n)){
    		printf("%d
    ",ivn[n]);
    	}
    	return 0;
    }
    

      

     欧拉函数:

    int euler(int n){//求某个数的欧拉函数 
        int ret=n;
        for(int i=2;i<=sqrt(n);i++){
            if(n%i==0){
                ret=ret/i*(i-1);
                while(n%i==0)
                n/=i;
            }
        }
        if(n>1)ret=ret/n*(n-1);
        return ret;
    }
    void findphi(){//埃拉托斯特尼筛求欧拉函数
        phi[1]=1;
        for(int i=2;i<=1e5;i++){
            phi[i]=i;
        }
        for(int i=2;i<=1e5;i++){
            if(phi[i]==i)
            for(int j=i;j<=1e5;j+=i){
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
    void eulorphi(){//欧拉筛求欧拉函数 
        phi[1]=1;
        memset(vis,0,sizeof(vis));
        for(int i=2;i<=1e5;i++){
            if(vis[i]==0){
                pri[++pri[0]]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=pri[0]&&i*pri[j]<=1e5;j++){
            //    cout<<i<<" "<<pri[j]<<" "<<phi[i]<<" "<<phi[pri[j]]<<endl;
                    vis[i*pri[j]]=1;    
                    if(i%pri[j]==0){
                        phi[i*pri[j]]=phi[i]*pri[j];
                        break;
                    }
                    phi[i*pri[j]]=phi[i]*phi[pri[j]];
                }
        }
        for(int i=1;i<=100;i++){
            output(phi[i]);
            cout<<" ";
            if(i%10==0)
            cout<<endl;
        }
    }

    素数筛:

    void ai(){//埃氏筛 
    	int vis[maxn];
    	memset(vis,0,sizeof(vis));
    	int ss[maxn];
    	int cnt=0;
    	for(int i=2;cnt<=100;i++){
    		if(vis[i]==0){
    			ss[++cnt]=i;
    			for(int j=i*i;j<=maxn;j+=i){
    				vis[j]=1;
    			}
    		}
    	}
    	for(int i=1;i<=100;i++){
    		output(ss[i]);
    		printf(" ");
    		if(i%10==0){
    			printf("
    ");
    		}
    	}
    } 
    

      

    void eulorpri(){//欧拉筛
    	memset(vis,0,sizeof(vis));
    	for(int i=2;i<=1e5;i++){
    		if(vis[i]==0){
    			pri[++pri[0]]=i;
    		}
    		for(int j=1;j<=pri[0]&&i*pri[j]<=1e5;j++){
    			vis[i*pri[j]]=1;
    			if(i%pri[j]==0)//代码核心
    			break;
    		}
    	}
    	for(int i=1;i<=100;i++){
    		output(pri[i]);
    		cout<<" ";
    		if(i%10==0)
    		cout<<endl;
    	}
    }
    

      

  • 相关阅读:
    Nova官方资料入口处
    LeetCode 有效的数独
    LeetCode 两数之和
    LeetCode 移动零
    安装OpenStack Queens版本的教程推荐
    删除排序数组中的重复项
    (转载)OpenStack client 调用分析
    (转载)基于Linux C的socket抓包程序和Package分析
    Maven的具体使用和优点
    关于 Javascript 学习,有哪些好的博客或者网站推荐?
  • 原文地址:https://www.cnblogs.com/Zhi-71/p/10547480.html
Copyright © 2011-2022 走看看