【HDU 4992】 Primitive Roots (原根)
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
25Sample Output
3
2 3 8 12 13 17 22 23
求出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。
代码如下:
#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 (原根)的更多相关文章
- HDU - 4992 Primitive Roots (原根)
模板题,可用于求一个数的所有原根. #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f ...
- hdu 4992 Primitive Roots 【求原根模板】
题目链接 大题流程: 判定是否有原根->求出最小原根->利用最小原根找出全部原根 #include<bits/stdc++.h> using namespace std; ty ...
- POJ 1284 Primitive Roots 原根
题目来源:POJ 1284 Primitive Roots 题意:求奇素数的原根数 思路:一个数n是奇素数才有原根 原根数是n-1的欧拉函数 #include <cstdio> const ...
- POJ1284 Primitive Roots (原根)
题目链接:http://poj.org/problem?id=1284 题目描述: 题目大意: 一个质数原根的个数 题解: 结论题 一个数n的原根的个数等于$\varphi(\varphi(n))$ ...
- POJ 1284:Primitive Roots(素数原根的个数)
Primitive Roots Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5709 Accepted: 3261 Descr ...
- POJ 1284 Primitive Roots 数论原根。
Primitive Roots Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2479 Accepted: 1385 D ...
- poj 1284 Primitive Roots (原根)
Primitive Roots http://poj.org/problem?id=1284 Time Limit: 1000MS Memory Limit: 10000K Descr ...
- POJ1284 Primitive Roots [欧拉函数,原根]
题目传送门 Primitive Roots Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5434 Accepted: ...
- 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 ...
随机推荐
- 获取当前时间日期并格式化--JS
工作当中,总是遇到很多觉得不错的JS脚本.现在觉得还是找个地方记录下来,以后可以随时查看. /** *获取当前时间日期并格式化 */ function getNowDate(){ var mydate ...
- CentOS6.3挂载读写NTFS分区
CentOS不像Fedora,默认是没有自动挂载NTFS的,而它可以利用NTFS-3G来实现挂载及读写. NTFS-3G 是一个开源的软件,可以实现 Linux.Free BSD.Mac OSX.Ne ...
- 20160328 javaweb Cookie 小练习
利用cookie实现历史记录浏览: 由于是简单演示,所以直接用javabean 取代数据库了 数据存储类: package com.dzq.dao; import java.util.*; impor ...
- Java Web应用启动间隔执行的程序
Reference:<Java定时器timer.schedule在Web中间隔执行任务和定时><[Java]Timer和TimerTask详解> 做了一个Demo,完成如下的功 ...
- Python入门 学习笔记 (二)
今天学习了一些简单的语法规则,话不多说,开始了: 二.数据类型 常用数据类型中的整形和浮点型就不多说了. 1.字符串 ...
- Codevs 1507 酒厂选址
1507 酒厂选址 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒 ...
- You have new mail in /var/spool/mail/root 烦不烦你(转)
转自(http://blog.csdn.net/yx_l128125/article/details/7425182) 有时在进入系统的时候经常提示You have new mail in /var/ ...
- Debian vim没有颜色的解决办法
最近在研究Linux kali 3.12-kali1-amd64 Debian 3.12.6-2kali1 x86_64 GNU/Linux Debian的内核 发现vim竟然没有颜色,root或 ...
- [C#]『PLINQ』任务并行库使用小计
并行 LINQ (PLINQ) 是 LINQ to Objects 的并行实现. PLINQ 实现完整的 LINQ 标准查询运算符集作为 T:System.Linq 命名空间的扩展方法,并具有用于并行 ...
- 采用python获得并修改文件编码(原创)
windows和linux采用了不同的编码,这让很多人伤透了脑经,这里我采用了Python的chardet库获得代码的编码,然后修改编码. 1.首先需要安装chardet库,有很多方式,我才用的是比较 ...