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. 查看kindle paperwhite2上卡索引书籍的方法

    昨天kindle耗电量突然加快,经过检查和网络搜索得知是卡索引导致的耗电量增大.我自己通过关闭索引的方式解决了这个问题. 在这个过程中发现了一个可以直接找到所有卡索引书籍的方法,在此分享一下. 首先打 ...

  2. jedis应用实例

    最近将redis整合到项目中,将redis作为cache使用,未来进一步作为消息推送使用.我通过jedis和spring配置实现操作redis. spring配置 <!-- redis配置 -- ...

  3. Mysql统计同一字段不同值的个数

    按照 Name 的名字分组,对 Value 值为 0 和 1 的个数进行统计 end) value0, end) value1 from new_table group by name: 结果:

  4. 如何在eclipse使用StaggeredGridView

    概述  现在的开发工具基本都用AndroidStudio了.网上的开源框架也是.比如做瀑布式UI的StaggeredGridView,还有导航页的PagerSlidingTabStrip等. 那么电脑 ...

  5. angularjs ios title不能修改的bug的解决方法

    在app.js加入下面这句代码 就可以解决. function ($rootScope, $state, $stateParams, $log, httpService, apiUrl, cookie ...

  6. DBHelper 数据库帮助类

    /// <summary> /// 数据库帮助类 /// <author>vito</author> /// </summary> public cla ...

  7. java数据同步陷阱

    并发,我的理解就是同时运行多个程序.同时,难以避免的就是数据的同步问题,如果数据同步问题处理不好就很容易造成程序出现bug,当然,对于其造成的危害,不加详述. 首先,来看一个简单的例子,当然,这个例子 ...

  8. 通过 OpenNI 建立 Kinect 3D Point Cloud

    這篇還是算延續前一篇的<透過 OpneNI 合併 Kinect 深度以及彩色影像資料>.在可以透過 OpenNI 讀取到 Kinect 的深度.色彩資訊之後,其實就可以試著用這些資訊,來重 ...

  9. (转)Libevent(1)— 简介、编译、配置

    转自:http://name5566.com/4190.html 参考文献列表:http://www.wangafu.net/~nickm/libevent-book/ 此文编写的时候,使用到的 Li ...

  10. ubuntu mint 开机启动项管理

    使用工具 sysv-rc-conf,需要安装. 点击打开链接http://blog.chinaunix.net/uid-21516619-id-1825027.html