P6091-[模板]原根
正题
题目链接:https://www.luogu.com.cn/problem/P6091
题目大意
给出一个数\(p\),求出它的所有在\([0,p]\)的原根。
解题思路
原根的定义,\(\delta_p(a)\)表示一个最小的\(n\)使得\(a^n\equiv1(mod\ p)\),若\(gcd(a,p)=1\)且\(\delta_p(a)=\varphi(p)\)则\(a\)为\(p\)的一个原根。
两个个结论就是一个数有原根当且仅当它为\(2,4,p^a,2p^a\)(其中\(p\)为奇质数,\(a\in N^+\))。还有若\(g\)表示最小正原根,那么其他原根可以被表示为\(g^k\% p(\ gcd(\varphi(p),k)=1\ )\)。
这两个结论在洛谷题解都有详细证明,这里就不多赘述了。
那么考虑如何求出最小正原根,因为原根的数量大约有\(\varphi(\varphi (p))\)个,所以密集度比较高,据说最小正原根约是\(O(n^{2.5})\)级别的。
所以考虑直接枚举,但是我们判定的时候肯定不能从\(1\sim \varphi(p)\)枚举来判断。
我们还需要用到一个结论就是如果对于\(gcd(a,p)=1\)且\(a^k\equiv 1(mod\ p)\)(也就是\(k\)是\(a\)模\(n\)的阶),那么有\(k|\varphi(p)\)。所以我们需要判定\(\varphi(p)\)的所有因子?看起来还是很大,但是我们显然有\(a^k\equiv 1(mod\ p)\)那么\(a^{kx}\equiv1(mod\ p)\)其中\(x\in N^+\)。所以我们只需要枚举\(\frac{\varphi(p)}{k}\)(其中\(k\)是\(\varphi(p)\)的质因子)即可,因为这些数包含了其他数的倍数。
时间复杂度\(O(n^{2.5}\log n+n\log n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const ll N=1e6+10;
ll T,n,d,cnt,phi[N],pri[N];
bool v[N],rt[N];
vector<int> q;
void prime(){
phi[1]=1;
for(ll i=2;i<N;i++){
if(!v[i])pri[++cnt]=i,phi[i]=i-1;
for(ll j=1;j<=cnt&&i*pri[j]<N;j++){
v[i*pri[j]]=1;
if(i%pri[j]==0){
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
rt[2]=rt[4]=1;
for(ll i=2;i<=cnt;i++){
for(ll j=1;j<N;j*=pri[i])rt[j]=1;
for(ll j=2;j<N;j*=pri[i])rt[j]=1;
}
return;
}
ll power(ll x,ll b,ll p){
ll ans=1;
while(b){
if(b&1)ans=ans*x%p;
x=x*x%p;b>>=1;
}
return ans;
}
ll gcd(ll x,ll y)
{return (!y)?x:gcd(y,x%y);}
void dec_phi(ll x){
for(ll i=1;i<=cnt&&pri[i]*pri[i]<=x;i++)
if(x%pri[i]==0){
q.push_back(pri[i]);
while(x%pri[i]==0)x/=pri[i];
}
if(x!=1)q.push_back(x);
return;
}
bool check(ll x){
if(power(x,phi[n],n)!=1)return 0;
for(ll i=0;i<q.size();i++)
if(power(x,phi[n]/q[i],n)==1)
return 0;
return 1;
}
signed main()
{
scanf("%lld",&T);
prime();
while(T--){
scanf("%lld%lld",&n,&d);q.clear();
if(!rt[n]){printf("0\n\n");continue;}
dec_phi(phi[n]);ll g=1;
while(!check(g))g++;
ll tmp=1;q.clear();
for(ll i=1;i<=phi[n];i++){
tmp=tmp*g%n;
if(gcd(phi[n],i)==1)
q.push_back(tmp);
}
printf("%lld\n",q.size());
sort(q.begin(),q.end());
for(ll i=1;i<=q.size()/d;i++)
printf("%lld ",q[i*d-1]);
putchar('\n');
}
return 0;
}
P6091-[模板]原根的更多相关文章
- x^a=b(mod c)求解x在[0,c-1]上解的个数模板+原根求法
/************************************* 求解x^a=b(mod c) x在[0,c-1]上解的个数模板 输入:1e9>=a,b>=1,1e9>= ...
- FFT模板 生成函数 原根 多项式求逆 多项式开根
FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...
- hdu 4992 Primitive Roots 【求原根模板】
题目链接 大题流程: 判定是否有原根->求出最小原根->利用最小原根找出全部原根 #include<bits/stdc++.h> using namespace std; ty ...
- luogu P6091 原根
LINK:原根 再复习一下原根 防止考场上要NTT求原根的时候不会求... 这道题要求求出n之内的所有原根 根据原根的定义. 原根指 若x对于模n的阶为phi(n)且\(1\leq x\leq n\) ...
- 多项式FFT相关模板
自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h& ...
- uestc_retarded 模板
虽然这个队,以后再也没有了,但是他的模板,是永垂不朽的![误 #include <ext/pb_ds/priority_queue.hpp> __gnu_pbds::priority_qu ...
- 多项式细节梳理&模板(多项式)
基础 很久以前的多项式总结 现在的码风又变了... FFT和NTT的板子 typedef complex<double> C; const double PI=acos(-1); void ...
- 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)
注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...
- FFT/NTT总结+洛谷P3803 【模板】多项式乘法(FFT)(FFT/NTT)
前言 众所周知,这两个东西都是用来算多项式乘法的. 对于这种常人思维难以理解的东西,就少些理解,多背板子吧! 因此只总结一下思路和代码,什么概念和推式子就靠巨佬们吧 推荐自为风月马前卒巨佬的概念和定理 ...
- NTT模板
NTT(快速数论变换)用到的各种素数及原根: https://blog.csdn.net/hnust_xx/article/details/76572828 NTT多项式乘法模板 #include&l ...
随机推荐
- The requested PHP extension ext-http * is missing from your system. Install or enable PHP's http ex
composer.json 包含 "require": { "ext-http": "*" } 删掉 "ext-http&quo ...
- WebAPI 自定义过滤
自定义filter 类过滤 ------------------------------------------------------------------------- public class ...
- 【java web】过滤器、拦截器、监听器的区别
一.对比: 1.1 过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对actio ...
- spring的异常处理
出自于:https://blog.csdn.net/he90227/article/details/46309297 ---- 利用Spring进行统一异常处理的两种方式. 原文:https:// ...
- js对url进行编码和解码
编码 只有 0-9[a-Z] $ - _ . + ! * ' ( ) , 以及某些保留字,才能不经过编码直接用于 URL. 例如:搜索的中文关键字,复制网址之后再粘贴就会发现该URL已经被转码. 1. ...
- Python - 面向对象编程 - 什么是 Python 类、类对象、实例对象
什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html Python 类 类定义语法 最简单的类定义看起来像这样 class ClassName: ...
- windows安装trojan记录
1.trojan 客户端安装教程 https://v2raytech.com/trojan-clients/ 2.chrome安装插件(crx文件)教程 https://www.jianshu.com ...
- Spring Boot +Vue 项目实战笔记(一):使用 CLI 搭建 Vue.js 项目
前言 从这篇文章开始,就进入真正的实践了. 在前端项目开发中,我们可以根据实际情况不同程度地使用 Vue.利用 Vue CLI(或写成 vue-cli,即 Vue 脚手架)搭建出来的项目,是最能体现 ...
- Kickstart部署多系统
原文转自:https://www.cnblogs.com/itzgr/p/10029587.html作者:木二 目录 一 准备 1.1 完整架构:Kickstart+DHCP+HTTP+TFTP+PX ...
- MySQL主库手动复制至从库
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 主库手动复制至从库 1.1 Master主库锁表 1.2 主库备份 1.3 从 ...