题解 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!!!\)

本题第一篇题解,求过

posted @ 2020-08-28 10:15  ADay526  阅读(105)  评论(0)    收藏  举报