原根 学习笔记

主要参考这里:
http://www.cnblogs.com/autsky-jadek/p/7496178.html
https://blog.csdn.net/a27038/article/details/77203892

定义:

定义\(a\)\(m\)的阶为,使得\(a^t\equiv1\ (mod\ m)\)成立的最小正整数\(t\)\(a,m\)互质)。用\(\delta_m(a)\)表示。
\(a,m\)互质且\(\varphi(m)=\delta_m(a)\)时,则称\(a\)为模\(m\)的一个原根。

\(m\)存在原根的充要条件:\(m=2,4,p^a,2p^a\),其中\(p\)是奇素数。
若模一个数\(p\)存在原根,那么其原根个数为\(\varphi(\varphi(p))\)

求模\(P\)的原根:

\(P\)是质数,将\(P-1\)质因数分解,即令\(P-1=\prod_{i=1}^kp_i^{a_i}\)
若对于\(i=1,2,...,k\),都有\[g^{\frac{P-1}{p_i}}\not\equiv 1\ (mod\ P)\]

那么\(g\)就是\(P\)的一个原根(\(g\)可以直接枚举,通常原根不会太大)。

\(P\)是合数,将\(P-1\)换成\(\varphi(P)\)即可。

性质:

\(g\)是模\(p\)的一个原根,则\(g,g^2,...,g^{\varphi(p)}\)在模\(p\)意义下两两不同,且恰好是小于\(p\)且与\(p\)互质的\(\varphi(p)\)个正整数的一个排列。

下面考虑\(p\)是质数的情况(合数一样吗我不太清楚啊...)

\(g^t\equiv a\ (mod\ p)(1\leq t\leq p-1)\),则相应的指数\(t\)被称为\(g\)为底的\(a\)\(p\)的指标。若\(p,g\)已知,则记指标为\(I(a)\),即\(I(a)=t\)

那么有指标法则
\[\begin{aligned}I(ab)&\equiv I(a)+I(b)\ (mod\ p-1)\ [乘积法则]\\I(a^k)&\equiv kI(a)\ (mod\ p-1)\ [幂法则]\end{aligned}\]

这样就可以将乘法化为加法,与连续数学中的对数很相似,因此指标也叫做离散对数。
1143196-20181130151715876-110438255.png

下面是一道求原根的模板题:
51Nod.1135.[模板]原根

//46ms  1,880KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e6+5;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
inline int FP(int x,int k,int mod)
{
    int t=1;
    for(; k; k>>=1,x=1ll*x*x%mod)
        if(k&1) t=1ll*t*x%mod;
    return t;
}
int Find_root(int P)
{
    static int p[N];
    int cnt=0,x=P-1;
    for(int i=2; i*i<=x; ++i)
        if(!(x%i))
        {
            p[++cnt]=i;
            while(!(x%i)) x/=i;
        }
    if(x!=1) p[++cnt]=x;
    for(int x=2; ; ++x)
    {
        bool ok=1;
        for(int i=1; i<=cnt; ++i) if(FP(x,(P-1)/p[i],P)==1) {ok=0; break;}
        if(ok) return x;
    }
    return -1;
}

int main()
{
    printf("%d\n",Find_root(read()));
    return 0;
}

另一道例题:BZOJ.3992.[SDOI2015]序列统计

转载于:https://www.cnblogs.com/SovietPower/p/10044472.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值