51nod 1135 原根(原根)

素数原根求法
本文介绍了一种求解素数原根的有效算法。通过预处理出素数P-1的所有质因数,并利用快速幂运算,判断a是否为P的原根。核心在于验证a的指数是否满足特定条件,确保其作为原根的唯一性。

题意

题目链接

Sol

可以证明素数的原根不会超过他的\(\frac{1}{4}\)

那么预处理出\(P - 1\)的所有的质因数\(p_1, p_2 \dots p_k\),暴力判断一下,如果$\exists i, a^{\frac{P - 1}{p_i}} \equiv 1 \pmod {P - 1} $

那么说明\(a\)不是\(P\)的原根,因为根据原根的定义,需要保证\(P-1\)是第一个满足\(a^{P - 1} \equiv 1 \pmod {P - 1}\)的数

#include<cstdio>
using namespace std;
const int MAXN = 1e6 + 10;
int fp(int a, int p, int mod) {
    int base = 1;
    while(p) {
        if(p & 1) base = 1ll * base * a % mod; 
        a = 1ll * a * a % mod; p >>= 1;
    }
    return base;
}
int GetG(int x) {
    static int q[MAXN]; int tot = 0, tp = x - 1;
    for(int i = 2; i * i <= tp; i++) {//这里是i * i 
        if(!(tp % i)) {
            q[++tot] = i;
            while(!(tp % i)) tp /= i;
        }
    }
    if(tp > 1) q[++tot] = tp;
    for(int i = 2, j; i <= x - 1; i++) {
        for(j = 1; j <= tot; j++) if(fp(i, (x - 1) / q[j], x) == 1) break;
        if(j == tot + 1) return i;
    }
}
int main() {
    int P;
    scanf("%d", &P);
    printf("%d", GetG(P));
    return 0;
}
/*
1000000007
*/

转载于:https://www.cnblogs.com/zwfymqz/p/10027150.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值