zoukankan      html  css  js  c++  java
  • [学习笔记]原根

    [学习笔记]原根

    前言

    这里只是简要概述一下,我也不会证明,防止忘记。

    一些定义

    1.欧拉定理

    [a^{varphi(m)}equiv 1 mod m,aperp m ]

    2. 阶

    满足 (a^nequiv1mod m) 的最小正整数 (n) 称为 a 模 m 的阶 ,记作 (delta_m(a)).

    于是有恒等式 (a^{delta_m(a)}equiv1mod m)

    3.原根

    [min N^+,ain Z,aperp m,delta_m(a)=varphi(m) ]

    同时满足这四个条件的称 a 为 m 的原根。

    容易知道可以将所有 a 映射到 ([1,m-1])
    并且原根还有一个重要的性质:

    [a^0,a^1,a^2,a^3.....a^{varphi(p)-1}mod p,互不相等 ]

    阶的性质

    性质1

    [a^nequiv1mod mRightarrow delta_m(a)|n ]

    性质2

    (delta_m) 是一个积性函数

    性质3

    [aperp m Rightarrowdelta_m(a^k)=frac{delta_ma}{gcd(delta_ma,k)} ]

    关于原根的定理

    原根的分布

    有且仅有1,2,4,奇素数的正整数幂和幂的两倍有原根

    原根的判断

    对于一个 (a) 满足 (aperp m)

    [forall p|varphi(m),a^{frac{varphi(m)}{p}} otequiv 1mod m ]

    那么a是m的一个原根

    原根的扩散

    基于一个最小的原根 g 可以得出其他所有的原根。那些原根(g')满足

    [g'equiv g^xmod m , xin(1,varphi(m))且xperp varphi(m) ]

    CODE

    Luogu 的模板而已

    const int MAXN=1e6+5;
    bool has[MAXN],isp[MAXN];
    int prime[MAXN],t,n,d,pphi[MAXN],ans[MAXN];
    inline int get_phi(int x){
    	int res=x;
    	pphi[0]=0;
    	for(int i=1;prime[i]*prime[i]<=x;++i){
    		if(x%prime[i]==0)res=res/prime[i]*(prime[i]-1);
    		while(x%prime[i]==0)x/=prime[i];
    	} 
    	if(x>1)res=res/x*(x-1);
    	for(int i=1;prime[i]<=res;++i)if(res%prime[i]==0)pphi[++pphi[0]]=prime[i];
    	return res;
    }
    inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
    inline int ksm(int a,int b,int mod){
    	int res=1;
    	for(;b;b>>=1,a=(a*a)%mod)if(b&1)res=(res*a)%mod;
    	return res;
    }
    signed main(){
    	has[1]=has[2]=has[4]=1;
    	fe(i,2,MAXN){
    		if(!isp[i])prime[++prime[0]]=i;
    		for(int j=1;j<=prime[0]&&prime[j]*i<MAXN;++j){
    			isp[i*prime[j]]=1;
    			if(i%prime[j]==0)break;
    		}
    	}
    	fe(i,2,prime[0]){
    		int po=prime[i];
    		while(po<MAXN){
    			has[po]=1;
    			if(po*2<MAXN)has[po*2]=1;
    			po*=prime[i];
    		}
    	}
    	t=read();
    	while(t--){
    		n=read(),d=read();
    		ans[0]=0;
    		if(!has[n]){puts("0"),puts("");continue;}
    		int phi=get_phi(n);
    		int g;
    		for(g=1;g<=phi;++g)if(gcd(g,n)==1){
    			int fl=0;
    			fe(j,1,pphi[0])if(ksm(g,phi/pphi[j],n)==1){
    				fl=1;break;
    			}if(!fl)break;
    		}
    		int base=g;
    		for(int x=1;x<=phi;++x,g=(g*base)%n)if(gcd(x,phi)==1)ans[++ans[0]]=g;
    		sort(ans+1,ans+ans[0]+1);
    		printf("%lld
    ",ans[0]);
    		for(int i=d;i<=ans[0];i+=d)printf("%lld ",ans[i]);
    		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    HDFS的滚动升级: Rolling Upgrade
    HDFS自定义小文件分析功能
    HDFS自定义小文件分析功能
    HDFS Federation机制
    HDFS Federation机制
    Confluence 6 配置一个数据源连接
    Confluence 6 在数据源连接中启用校验查询
    Confluence 6 从你的 JDBC 连接中直接启用校验查询
    Confluence 6 针对你的数据库类型确定校验 SQL
    Confluence 6 从关闭的连接中恢复
  • 原文地址:https://www.cnblogs.com/clockwhite/p/14247369.html
Copyright © 2011-2022 走看看