题解: 原根判断
题目背景
截止 2025 年 3 月,本题可能超出了 GESP 考纲范围。在该时间点下,原根是 NOI 大纲 8 级知识点(NOI 级),且不属于 GESP 大纲内容。需要注意,GESP 大纲和 NOI 大纲是不同的大纲。 若对题目中原根这一概念感兴趣,可以学习完成 【模板】原根。
~本萌新只是个五年级刚学oi的蒟蒻,本想考个五级,结果qwq……我的两道编程题都ac了 \(^v^)/~
题意:
对于质数
-
-
- 对于任意
1\le i<p-1 均有g^i\bmod{p}\neq1 。
其中
给出一个整数
保证
思路:
要想让
-
-
- 对于任意
1\le i<p-1 均有a^i\bmod{p}\neq1 ,如何判断?
枚举每个
正难则反,只需要知道
在
假设
wow,有周期,每
因为
诶,我们忽略了
也就是说我们要将
又知道
所以只用找
代码(含注释):
//c++
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
vector<ll>yin; //表示p-1的因数
ll fpow(ll a,ll b,ll p){//快速幂
a%=p;
if(b==1)return a;
if(b==0)return 1;
if(b&1)return a*fpow(a*a%p,(b>>1),p)%p;
return fpow(a*a%p,(b>>1),p);
}
void find_yin(ll x){ //找因数
while(yin.size()) //清空
yin.pop_back();
for(ll i=2;i*i<=x;i++){
if(x%i==0){
yin.push_back(i);
yin.push_back(x/i);
}
}
return ;
}
void doing(){//求出每次答案
ll p,a;
cin>>a>>p;
if(fpow(a,p-1,p)!=1){ //条件2
puts("No");
return ;
}
find_yin(p-1); //找p-1的因数
for(int i=0;i<yin.size();i++){
ll y=yin[i]; //枚举每个因数
if(fpow(a,y,p)==1){//满足条件4(不满足条件3)
puts("No");
return ;
}
}
puts("Yes");
return ;
}
int main(){
int t;
cin>>t;
while(t--){
doing();
}
return 0;
}
复杂度:
- 时间:
O(T\times(\log n\times\sqrt n+\log n+\sqrt n)) - 空间:
O(\sqrt n) 鸣谢
- @_UltraPitcher
- @Chase12345