Description

We say that integer x, 0 < x < n, is a primitive root modulo n if and only if the minimum positive integer y which makes x y = 1 (mod n) true is φ(n) .Here φ(n) is an arithmetic function that counts the totatives of n, that is, the positive integers less than or equal to n that are relatively prime to n. Write a program which given any positive integer n( 2 <= n < 1000000) outputs all primitive roots of n in ascending order.

Input

Multi test cases. 
Each line of the input contains a positive integer n. Input is terminated by the end-of-file seperator.

Output

For each n, outputs all primitive roots of n in ascending order in a single line, if there is no primitive root for n just print -1 in a single line.

Sample Input

4
25

Sample Output

3
2 3 8 12 13 17 22 23
 
【题意】
  求n的所有原根,若没有就输出-1(n<=10^6)
 
【分析】
  

求出n的所有原根,不存在原根输出-1。

原根的定义题目已经给出,对于n的原根x,则满足x的y次幂模n等于1的最小y是n的欧拉函数值phi(n),也就是小于等于n且与n互质的个数。

官方的题解里面说暴力求出一个原根来,然后利用结论:

如果g是模m的原根,整数d>=0,则g的d次幂是模m的原根的一个充要条件是d和phi(m)互质。

d暴力枚举:

一个是如果gcd(g, m)=1,且g^d=1(mod m),则d为phi(m)的一个因子。换句话说如果g是m的原根,那么对于phi(m)的所有因子d(不包含phi(m)本身),g^d=1(mod m)是不成立的。我们可以通过枚举phi(m)的质因子以及g^phi(m)=1(mod m)是否成立来判断g是否是模m的原根。

然后有些不存在原根的数字利用另一条性质排除:

模m有原根的充要条件是m=2,4,p^n, 2p^n,p为奇质数,n任意正整数。

如果m没有满足上述条件,就直接输出-1。

http://blog.csdn.net/hongrock/article/details/39179291


代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define LL long long
#define Maxn 1000010 int phi[Maxn],pri[Maxn],pl;
bool q[Maxn],qs[Maxn]; int gcd(int a,int b)
{
if(b==) return a;
return gcd(b,a%b);
} void get_phi(int mx)
{
pl=;
memset(q,,sizeof(q));
memset(qs,,sizeof(qs));
phi[]=;
for(int i=;i<=mx;i++)
{
if(q[i]) pri[++pl]=i,qs[i]=i==?:,phi[i]=i-;
for(int j=;j<=pl;j++)
{
if(i*pri[j]>mx) break;
q[i*pri[j]]=;
if(i%pri[j]==)
{
phi[i*pri[j]]=phi[i]*pri[j];
if(qs[i]) qs[i*pri[j]]=;
}
else phi[i*pri[j]]=phi[i]*(pri[j]-);
if(i%pri[j]==) break;
}
}
for(int i=mx/;i>=;i--) if(qs[i]) qs[*i]=;
qs[]=;qs[]=;
} int qpow(int x,int y,int p)
{
LL ans=,xx=x,pp=p;
while(y)
{
if(y&) ans=(ans*xx)%pp;
xx=(xx*xx)%pp;
y>>=;
}
return (int)ans;
} int np[Maxn],nl;
void div(int x)
{
nl=;
for(int i=;pri[i]*pri[i]<=x;i++) if(x%pri[i]==)
{
np[++nl]=pri[i];
while(x%pri[i]==) x/=pri[i];
}
if(x>) np[++nl]=x;
} int ffind(int n)
{
div(phi[n]);
for(int i=;i<=n;i++)
{
if(qpow(i,phi[n],n)!=) continue;
bool ok=;
for(int j=;j<=nl;j++)
{
if(qpow(i,phi[n]/np[j],n)==) {ok=;break;}
}
if(!ok) continue;
return i;
}
return -;
} int op[Maxn]; void output(int g,int n)
{
op[]=;
op[++op[]]=g;
LL M=(LL)n,now=(LL)g,gg=(LL)g;
for(int i=;i<phi[n];i++)
{
now=(now*gg)%M;
if(gcd(i,phi[n])==) op[++op[]]=(int)now;
}
} int main()
{
get_phi();
int n;
while(scanf("%d",&n)!=EOF)
{
if(!qs[n]) {printf("-1\n");continue;}
int g=ffind(n);
output(g,n);
sort(op+,op+op[]+);
for(int i=;i<=op[];i++) printf("%d ",op[i]);
printf("\n");
}
return ;
}

[HDU 4992]

2016-09-06 16:39:31

【HDU 4992】 Primitive Roots (原根)的更多相关文章

  1. HDU - 4992 Primitive Roots (原根)

    模板题,可用于求一个数的所有原根. #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f ...

  2. hdu 4992 Primitive Roots 【求原根模板】

    题目链接 大题流程: 判定是否有原根->求出最小原根->利用最小原根找出全部原根 #include<bits/stdc++.h> using namespace std; ty ...

  3. POJ 1284 Primitive Roots 原根

    题目来源:POJ 1284 Primitive Roots 题意:求奇素数的原根数 思路:一个数n是奇素数才有原根 原根数是n-1的欧拉函数 #include <cstdio> const ...

  4. POJ1284 Primitive Roots (原根)

    题目链接:http://poj.org/problem?id=1284 题目描述: 题目大意: 一个质数原根的个数 题解: 结论题 一个数n的原根的个数等于$\varphi(\varphi(n))$ ...

  5. POJ 1284:Primitive Roots(素数原根的个数)

    Primitive Roots Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5709 Accepted: 3261 Descr ...

  6. POJ 1284 Primitive Roots 数论原根。

    Primitive Roots Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2479   Accepted: 1385 D ...

  7. poj 1284 Primitive Roots (原根)

    Primitive Roots http://poj.org/problem?id=1284 Time Limit: 1000MS   Memory Limit: 10000K       Descr ...

  8. POJ1284 Primitive Roots [欧拉函数,原根]

    题目传送门 Primitive Roots Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5434   Accepted:  ...

  9. POJ_1284 Primitive Roots 【原根性质+欧拉函数运用】

    一.题目 We say that integer x, 0 < x < p, is a primitive root modulo odd prime p if and only if t ...

随机推荐

  1. 获取当前时间日期并格式化--JS

    工作当中,总是遇到很多觉得不错的JS脚本.现在觉得还是找个地方记录下来,以后可以随时查看. /** *获取当前时间日期并格式化 */ function getNowDate(){ var mydate ...

  2. CentOS6.3挂载读写NTFS分区

    CentOS不像Fedora,默认是没有自动挂载NTFS的,而它可以利用NTFS-3G来实现挂载及读写. NTFS-3G 是一个开源的软件,可以实现 Linux.Free BSD.Mac OSX.Ne ...

  3. 20160328 javaweb Cookie 小练习

    利用cookie实现历史记录浏览: 由于是简单演示,所以直接用javabean 取代数据库了 数据存储类: package com.dzq.dao; import java.util.*; impor ...

  4. Java Web应用启动间隔执行的程序

    Reference:<Java定时器timer.schedule在Web中间隔执行任务和定时><[Java]Timer和TimerTask详解> 做了一个Demo,完成如下的功 ...

  5. Python入门 学习笔记 (二)

      今天学习了一些简单的语法规则,话不多说,开始了:      二.数据类型                常用数据类型中的整形和浮点型就不多说了.                1.字符串     ...

  6. Codevs 1507 酒厂选址

    1507 酒厂选址 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒 ...

  7. You have new mail in /var/spool/mail/root 烦不烦你(转)

    转自(http://blog.csdn.net/yx_l128125/article/details/7425182) 有时在进入系统的时候经常提示You have new mail in /var/ ...

  8. Debian vim没有颜色的解决办法

    最近在研究Linux kali 3.12-kali1-amd64  Debian 3.12.6-2kali1  x86_64 GNU/Linux Debian的内核 发现vim竟然没有颜色,root或 ...

  9. [C#]『PLINQ』任务并行库使用小计

    并行 LINQ (PLINQ) 是 LINQ to Objects 的并行实现. PLINQ 实现完整的 LINQ 标准查询运算符集作为 T:System.Linq 命名空间的扩展方法,并具有用于并行 ...

  10. 采用python获得并修改文件编码(原创)

    windows和linux采用了不同的编码,这让很多人伤透了脑经,这里我采用了Python的chardet库获得代码的编码,然后修改编码. 1.首先需要安装chardet库,有很多方式,我才用的是比较 ...