题解 SP3713 【PROOT - Primitive Root】
实际发表时间:2020-04-08
原题链接
本题居然没人发题解...
这题考察了原根的性质,如果\(a\)是\(m\)的原根,那么——
存在最小的正整数\(d\)满足\(a^d\equiv 1(mod\; m)\),则有 \(d\)整除\(φ(m)\),因此\(Ordm(a)\)整除\(φ(m)\)。这里的\(d\)被称为\(a\)模\(m\)的阶,记为\(Ordm(a)\)。
——百度百科
即\(d\)为\(φ(m)\)的倍数
所以我们可以快速幂枚举\(a^i\)看它\(\% m\)的结果
又\(\because\)上面那个性质,我们的指数只枚举\(φ(m)\)的因数即可,且不枚举 \(1 \text{和}φ(m)\)。
如果枚举到的\(a^i \equiv 1(mod\; m)\)则输出\(\mathcal{NO}\),不然输出\(\mathcal{YES}\)
又因为有多组数据,可以先预处理\(φ(m)\)的因数
而且题目保证\(m\)为质数,所以\(φ(m)=m-1\)
代码:(用\(g\)代替\(a\),用\(p\)代替\(m\))
#include<bits/stdc++.h>
using namespace std;
const int N=7e4;
int p,n,g,fac[N];
inline long long qp(long long x,long long y,long long mod)//快速幂
{
long long res=1;
while(y)
{
if(y&1)res=res*x%mod;
y>>=1;
x=(x*x)%mod;
}
return res;
}
int main()
{
while(scanf("%d%d",&p,&n)&&p&&n)
{
p--; //Φ(p)=p-1
register int cnt=1;
for(register int i=2;i<=sqrt(p);i++)if(p%i==0)fac[cnt++]=i,fac[cnt++]=p/i;//预处理因数
while(n--)
{
scanf("%d",&g);
register bool flag=0;
for(register int i=1;i<cnt;i++)//枚举g^i
{
register int pw=qp(g,fac[i],p+1);
if(pw==1)
{
flag=1;
break;
}
}
if(flag)puts("NO");
else puts("YES");
}
}
return 0;
}
快速幂记得开\(long\;long!!!\)
本题第一篇题解,求过

浙公网安备 33010602011771号