luogu P6091 原根
LINK:原根
再复习一下原根 防止考场上要NTT求原根的时候不会求...
这道题要求求出n之内的所有原根 根据原根的定义。
原根指 若x对于模n的阶为phi(n)且\(1\leq x\leq n\) 那么称x为n的原根.
暴力做法枚举x 枚举phi(n)的因数 看其是否同余1.
复杂度nsqrt(n)左右。
考虑更快的做法 (去年省选骗分过样例也用了这个做法
考虑求出最小的原根g(暴力,但是很快. 对于剩下的原根都可以表示成g^k,条件为(k,phi(n))==1.(显然。
于是就做完了。值得一提的是我们还需要知道一个数字是否有原根。
有原根的必要充要条件:2,4,p^k,2*p^k.其中p为奇质数。
const int MAXN=1000010;
int T,top,cnt,n,maxx;
int p[MAXN],v[MAXN],phi[MAXN],vis[MAXN],s[MAXN],an[MAXN];
inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
inline void prepare()
{
phi[1]=1;
for(int i=2;i<=maxx;++i)
{
if(!v[i]){p[++top]=v[i]=i;phi[i]=i-1;}
rep(1,top,j)
{
if(maxx/i<p[j])break;
int ww=i*p[j];
v[ww]=p[j];
if(v[i]==p[j]){phi[ww]=phi[i]*p[j];break;}
phi[ww]=phi[i]*(p[j]-1);
}
}
vis[2]=1;vis[4]=1;
rep(2,top,i)
{
for(ll j=1*p[i];j<=maxx;j=j*p[i])vis[j]=1;
for(ll j=2*p[i];j<=maxx;j=j*p[i])vis[j]=1;
}
}
inline int ksm(ll b,int p,int mod)
{
ll cnt=1;
while(p)
{
if(p&1)cnt=cnt*b%mod;
b=b*b%mod;p=p>>1;
}
return cnt;
}
inline void fj(int x)
{
top=0;
for(int i=1;p[i]*p[i]<=x;++i)
if(x%p[i]==0)
{
s[++top]=p[i];
while(x%p[i]==0)x/=p[i];
}
if(x>1)s[++top]=x;
}
inline int check(int x,int p)
{
if(ksm(x,phi[p],p)!=1)return 0;
rep(1,top,i)
if(ksm(x,phi[p]/s[i],p)==1)return 0;
return 1;
}
inline int getg(int p)
{
rep(1,p-1,i)if(check(i,p))return i;
return 0;
}
inline void get_ans(int g,int p)
{
cnt=0;ll ww=1;
rep(1,phi[p],i)
{
ww=ww*g%p;
if(gcd(i,phi[p])==1)an[++cnt]=ww;
}
}
int main()
{
freopen("1.in","r",stdin);
get(T);maxx=1000000;prepare();
while(T--)
{
get(n);int d;get(d);
if(vis[n])
{
fj(phi[n]);
get_ans(getg(n),n);
sort(an+1,an+1+cnt);
put(cnt);
rep(1,cnt/d,i)printf("%d ",an[i*d]);
}
else puts("0");
puts("");
}
return 0;
}
luogu P6091 原根的更多相关文章
- luogu P5605 小 A 与两位神仙 - 原根
题目传送门 传送门 Subtask 1 直接模拟. Subtask 2 BSGS算法模板. Subtask 3 考虑模 $m$ 的任意一个原根 $g$. 假设 $g^{ra} \equiv x \pm ...
- P6091-[模板]原根
正题 题目链接:https://www.luogu.com.cn/problem/P6091 题目大意 给出一个数\(p\),求出它的所有在\([0,p]\)的原根. 解题思路 原根的定义,\(\de ...
- 数论入门2——gcd,lcm,exGCD,欧拉定理,乘法逆元,(ex)CRT,(ex)BSGS,(ex)Lucas,原根,Miller-Rabin,Pollard-Rho
数论入门2 另一种类型的数论... GCD,LCM 定义\(gcd(a,b)\)为a和b的最大公约数,\(lcm(a,b)\)为a和b的最小公倍数,则有: 将a和b分解质因数为\(a=p1^{a1}p ...
- 51nod1135(求最小原根)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135 题意:中文题诶- 思路:设m是正整数,a是整数,若a模 ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- [POJ1284]Primitive Roots(原根性质的应用)
题目:http://poj.org/problem?id=1284 题意:就是求一个奇素数有多少个原根 分析: 使得方程a^x=1(mod m)成立的最小正整数x是φ(m),则称a是m的一个原根 然后 ...
- 51nod 1135 原根
题目链接:51nod 1135 原根 设 m 是正整数,a是整数,若a模m的阶等于φ(m),则称 a 为 模m的一个原根.(其中φ(m)表示m的欧拉函数) 阶:gcd(a,m)=1,使得成立的最小的 ...
- hdu4992 Primitive Roots(所有原根)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4992 题意:给出n,输出n的所有原根. 思路:求出n的一个原根x,那么对于所以的i,i<phi( ...
随机推荐
- python爬京东(带GUI)
最近写了个专门爬百度的,后来又想爬京东的,还是采用上次的BeautifulSoup+requests模块 下面直接上代码,看不懂的可以看这篇文章或者注释来学习 #!/usr/bin/env pytho ...
- SimpleImputer 中fit和transform方法的简介
sklearn.impute.SimpleImputer 中fit和transform方法的简介 SimpleImputer 简介 通过SimpleImputer ,可以将现实数据中缺失的值通过同一列 ...
- mysql 时间自动更新问题
万恶的根据当前时间戳更新,有时候会自动更新,有时候又不会. 通过navicat 创建datetime类型的字段时,会自动勾选上根据当前时间戳更新.当更新数据的时候勾上这个的字段时间就会更改为当前的时间 ...
- bzoj4318OSU!*
bzoj4318OSU! 题意: 一个长度为n的序列,每个元素有一定概率是1,不是1就是0.连续x个1可以贡献x^3的分数,问期望分数. 题解: 期望dp.f1[i]表示连续到i的期望长度,f2[i] ...
- Docker 基础知识 - 使用卷(volume)管理应用程序数据
卷(volumes)是 Docker 容器生产和使用持久化数据的首选机制.绑定挂载(bind mounts)依赖于主机的目录结构,卷(volumes)完全由 Docker 管理.卷与绑定挂载相比有几个 ...
- Ethical Hacking - GAINING ACCESS(18)
CLIENT SIDE ATTACKS Backdooring ANY file Combine backdoor with any file - Generic solution. Users ar ...
- scratch编程——画笔模块画各种同心图案
我们今天是要用画笔来画出不同的同心图案,在画之前,我们先来了解一下画笔模块: 1.画笔模块的用法 画笔模块的用法就是在舞台上留下不同颜色粗细的线条,它的默认是情况是抬笔,我们在使用的时候要让角色移动到 ...
- idea 自动生成try/catch代码块的快捷键
好像每个人的快捷键可能不同:我的是 Alt+Shift+Z 网上查的是 Ctrl+Alt+T 如果都不是可以点选工具栏生成try/catch(并可查看到自己的快捷键是什么):Code->Su ...
- C++语法小记---string和int的相互转换
string和int的相互转换 string转int istringstream is(""); //构造输入字符串流,流的内容初始化为“12”的字符串 int i; is > ...
- 将数组内的元素循环左移P个位置
问题可以转化为将数组内前 n 个元素进行逆置,再将后(n-p)个元素逆置,最后将整个数组逆置 void Reverse(int A[],int pos1,int pos2){ // 将A[pos1]与 ...