专栏文章
题解: 原根判断
P11961题解参与者 164已保存评论 205
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 203 条
- 当前快照
- 1 份
- 快照标识符
- @miptrf0g
- 此快照首次捕获于
- 2025/12/03 17:48 3 个月前
- 此快照最后确认于
- 2025/12/03 17:48 3 个月前
题目背景
截止 2025 年 3 月,本题可能超出了 GESP 考纲范围。在该时间点下,原根是 NOI 大纲 8 级知识点(NOI 级),且不属于 GESP 大纲内容。需要注意,GESP 大纲和 NOI 大纲是不同的大纲。 若对题目中原根这一概念感兴趣,可以学习完成 【模板】原根。
~本萌新只是个五年级刚学oi的蒟蒻,本想考个五级,结果qwq……我的两道编程题都ac了 \(^v^)/~
题意:
对于质数 而言, 的原根 是满足以下条件的正整数:
- ;
- ;
- 对于任意 均有 。
其中 表示 除以 的余数。
给出一个整数 和质数 ,判断 是不是 的原根。
保证 ,,, 为质数。
思路:
要想让 是 的原根,必须满足三个条件:
- ,这条已被约束条件满足了,无需判断;
- ,写个快速幂, 就能判断;
- 对于任意 均有 ,如何判断?
枚举每个 ,依次用快速幂判断,但还是慢了。
正难则反,只需要知道 的结果,就知道 。
在 中,那个 可能满足 ?
假设 。
wow,有周期,每 个一循环,每个循环周期大小相等!
因为 我们提前判段为错误,并退出了,所以现在的 和 一定满足 。
诶,我们忽略了 ,!
也就是说我们要将 到 划分成若干段长度相同的循环周期,在 中,只有每小段的末尾,也就是 的因数的倍数,可能满足 。
又知道 的一个因数 ,使得 ,那么,这个因数的任意一个倍数 ,也都满足 。
所以只用找 的每一个因数 是否满足 ,就可以推出"对于任意 均有 "这个条件了
代码(含注释):
CPP//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;
}
复杂度:
- 时间:
- 空间:
鸣谢
相关推荐
评论
共 205 条评论,欢迎与作者交流。
正在加载评论...