题解:P11961 [GESP202503 五级] 原根判断

本文同步发布至 洛谷


题解:P11961 [GESP202503 五级] 原根判断

题外话

CCF 是不是放错题了?虽然这道题也比较简单,但是不符合五级的水准啊!!!

题目分析

根据题目的要求,有三个条件,其中第一个条件是最好判的,因为数据就已经保证了,当然如果你也想判一下也无所谓。

接下来就看第二个条件,非常显然是一个模板的快速幂,可以在 O ( log ⁡ n ) O(\log n) O(logn) 的时间复杂度内解决,也是比较容易的。

最难的就是第三个条件了,如果说你只想拿 40 分的话,也可以直接顺着打暴力,硬判,但是嘛,我们都是有追求的人,不能只关注者一点点的分,所以说我们要找规律。

我的数学老师杨老师,曾经说过一句话,正着来弄难,那就反着来弄,话句话说,这道题我们是不是可以直接反着判,看看哪些情况可能得到 1,哪些情况可能得不到 1。

接下来就是尝试。

如果说我们设 a k   m o d   p = 1 a^k \bmod p =1 akmodp=1,那么因为取余的两侧可以进行加,减,乘的运算,所以说我们又可以很轻松的得到这些式子 a k + 1   m o d   p = a 1   m o d   p a^{k+1}\bmod p=a^1 \bmod p ak+1modp=a1modp a k + 2   m o d   p = a 2   m o d   p a^{k+2} \bmod p=a^2 \bmod p ak+2modp=a2modp a k + n   m o d   p = a n   m o d   p a^{k+n} \bmod p=a^n\bmod p ak+nmodp=anmodp

那么基于这些式子,我们是不是可以发现这个是一个长度为 k k k 的一个循环周期?

同时我们根据条件 2,是不是发现这个长度周期只有可能是 p − 1 p-1 p1 的因数,那么我们直接枚举因数不就可以了?

这样的时间复杂度就是 O ( T × p − 1 × log ⁡ p − 1 ) O(T\times \sqrt{p-1}\times \log_{p-1}) O(T×p1 ×logp1)

代码实现

#include<bits/stdc++.h>
using namespace std;

long long quickpow(int a,int p,int mod){
	if (p==0)return 1;
	long long t=quickpow(a,p/2,mod);
	t=t*t%mod;
	if (p%2==1)t=t*a%mod;
	return t%mod;
}

int main(){
	int T;
	cin>>T;
	while (T--){
		int a,p;
		cin>>a>>p;
		if (quickpow(a,p-1,p)!=1){
			cout<<"No\n";
			continue;
		}
		bool flag=true;
		for (int i=2;i*i<=(p-1);i++){
			if ((p-1)%i==0){
				if (quickpow(a,i,p)==1||quickpow(a,(p-1)/i,p)==1){
					flag=false; 
					break;
				}
			}
		}
		if (flag)cout<<"Yes\n";
		else cout<<"No\n";
	} 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值