阶
要定义原根,先要引入数论中阶的概念。
阶的定义
设 a , m ∈ N + a,m\in\mathbb{N^+} a,m∈N+,且 a ⊥ m a\perp m a⊥m,使 a x ≡ 1 ( m o d m ) a^x\equiv 1\pmod m ax≡1(modm) 成立的最小正整数 x x x,称为 a a a 模 m m m 的阶,记为 ord m a \text{ord}_ma ordma。
阶的性质
说明:描述阶的性质时,默认
a
,
m
∈
N
+
a,m\in\mathbb{N^+}
a,m∈N+,且
a
⊥
m
a\bot m
a⊥m,即
o
r
d
m
a
\mathrm{ord}_m a
ordma 存在。
性质1
a
n
≡
1
(
m
o
d
m
)
a^n\equiv 1\pmod m
an≡1(modm) 的充要条件为
o
r
d
m
a
∣
n
\mathrm{ord}_ma|n
ordma∣n。
证明 设
o
r
d
m
a
=
x
\mathrm{ord}_ma=x
ordma=x。
首先证明充分性。设
n
=
p
x
n=px
n=px,其中
p
∈
N
+
p\in\mathbb{N^+}
p∈N+。则
a
n
≡
a
p
x
≡
1
(
m
o
d
m
)
a^n\equiv a^{px}\equiv1\pmod m
an≡apx≡1(modm);即
a
n
≡
1
(
m
o
d
m
)
a^n\equiv 1\pmod m
an≡1(modm)。
接下来证明必要性。设
n
=
p
x
+
q
n=px+q
n=px+q,其中
p
∈
N
+
p\in\mathbb{N^+}
p∈N+ ,且
0
≤
q
<
x
,
q
∈
N
0\le q<x,q\in\mathbb N
0≤q<x,q∈N。则
a
n
≡
a
p
x
+
q
≡
a
q
≡
1
(
m
o
d
m
)
a^n\equiv a^{px+q}\equiv a^q\equiv 1\pmod m
an≡apx+q≡aq≡1(modm),得到
a
q
≡
1
(
m
o
d
m
)
a^q\equiv 1\pmod m
aq≡1(modm),由于
x
x
x 是满足
a
x
≡
1
(
m
o
d
m
)
a^x\equiv1\pmod m
ax≡1(modm) 的最小正整数,又
0
≤
q
<
x
0\le q<x
0≤q<x,所以
q
=
0
q=0
q=0,故
x
∣
n
x\mid n
x∣n。
证毕。
推论1
o
r
d
m
a
∣
φ
(
m
)
\mathrm{ord}_ma\mid\varphi(m)
ordma∣φ(m)。
证明 由欧拉定理,
a
φ
(
m
)
≡
1
(
m
o
d
m
)
a^{\varphi(m)}\equiv1\pmod m
aφ(m)≡1(modm),故
o
r
d
m
a
∣
φ
(
m
)
\mathrm{ord}_ma\mid\varphi(m)
ordma∣φ(m)。
性质2 设
b
∈
N
+
b\in\mathbb N^+
b∈N+,若
a
≡
b
(
m
o
d
m
)
a\equiv b\pmod m
a≡b(modm),则
ord
m
a
=
ord
m
b
\text{ord}_ma=\text{ord}_mb
ordma=ordmb。
证明 首先
a
≡
b
(
m
o
d
m
)
a\equiv b\pmod m
a≡b(modm),可以设
b
=
a
+
k
m
,
k
∈
Z
b=a+km,k\in\mathbb Z
b=a+km,k∈Z。则
gcd
(
b
,
m
)
=
gcd
(
a
+
k
m
,
m
)
\gcd(b,m)=\gcd(a+km,m)
gcd(b,m)=gcd(a+km,m),由欧几里得算法
gcd
(
b
,
m
)
=
gcd
(
m
,
a
)
=
1
\gcd(b,m)=\gcd(m,a)=1
gcd(b,m)=gcd(m,a)=1,故
b
⊥
m
b\bot m
b⊥m,所以
o
r
d
m
b
\mathrm{ord}_mb
ordmb 存在。
接下来用反证法证明
ord
m
a
=
ord
m
b
\text{ord}_ma=\text{ord}_mb
ordma=ordmb。假设
ord
m
a
=
x
\text{ord}_ma=x
ordma=x,
ord
m
b
=
y
\text{ord}_mb=y
ordmb=y,且
x
≠
y
x\ne y
x=y。则
a
x
≡
(
b
−
k
m
)
x
≡
1
(
m
o
d
m
)
a^x\equiv(b-km)^x\equiv1\pmod m
ax≡(b−km)x≡1(modm),将
(
b
−
k
m
)
x
(b-km)^x
(b−km)x 用二项式定理展开,得到
b
x
≡
1
(
m
o
d
m
)
b^x\equiv1\pmod m
bx≡1(modm)。根据假设
o
r
d
m
b
=
y
\mathrm{ord}_mb=y
ordmb=y,故
x
>
y
x>y
x>y。然而,
b
y
≡
(
a
+
k
m
)
y
≡
1
(
m
o
d
m
)
b^y\equiv(a+km)^y\equiv1\pmod m
by≡(a+km)y≡1(modm),将
(
a
+
k
m
)
y
(a+km)^y
(a+km)y 用二项式定理展开,得到
a
y
≡
1
(
m
o
d
m
)
a^y\equiv1\pmod m
ay≡1(modm);由于
o
r
d
m
a
=
x
\mathrm{ord}_ma=x
ordma=x,故
x
<
y
x<y
x<y,产生矛盾;所以,
x
=
y
x=y
x=y,即
ord
m
a
=
ord
m
b
\text{ord}_ma=\text{ord}_mb
ordma=ordmb。
证毕。
性质3 设
p
,
q
∈
N
p,q\in\mathbb N
p,q∈N,
a
p
≡
a
q
(
m
o
d
m
)
a^p\equiv a^q\pmod m
ap≡aq(modm) 的充要条件为
p
≡
q
(
m
o
d
ord
m
a
)
p\equiv q\pmod {\text{ord}_ma}
p≡q(modordma)。
证明 首先证明充分性。设
p
=
k
1
o
r
d
m
a
+
r
p=k_1\mathrm{ord}_ma+r
p=k1ordma+r,
q
=
k
2
o
r
d
m
a
+
r
q=k_2\mathrm{ord}_ma+r
q=k2ordma+r,其中
k
1
,
k
2
,
r
∈
N
k_1,k_2,r\in\mathbb N
k1,k2,r∈N,且
0
≤
r
<
o
r
d
m
a
0\le r<\mathrm{ord}_ma
0≤r<ordma。则
a
p
≡
a
k
1
o
r
d
m
a
+
r
≡
a
r
(
m
o
d
m
)
a^p\equiv a^{k_1\mathrm{ord}_ma+r}\equiv a^r\pmod m
ap≡ak1ordma+r≡ar(modm),同理,
a
q
≡
a
r
(
m
o
d
m
)
a^q\equiv a^r\pmod m
aq≡ar(modm),故
a
p
≡
a
q
(
m
o
d
m
)
a^p\equiv a^q\pmod m
ap≡aq(modm)。充分性得证。
接下来证明必要性。不妨设
p
≥
q
p\ge q
p≥q,则
a
p
−
q
≡
1
(
m
o
d
m
)
a^{p-q}\equiv 1\pmod m
ap−q≡1(modm)。根据性质1,
ord
a
m
∣
p
−
q
\text{ord}_a m\mid p-q
ordam∣p−q,所以
p
≡
q
(
m
o
d
ord
m
a
)
p\equiv q\pmod {\text{ord}_ma}
p≡q(modordma)。必要性得证。
证毕。
性质4 令
ord
m
a
=
x
\text{ord}_ma=x
ordma=x,则
1
,
a
,
a
2
,
⋯
,
a
x
−
1
1,a,a^2,\cdots,a^{x-1}
1,a,a2,⋯,ax−1,模
m
m
m 两两不同余。
证明 下面用反证法证明。
假设
∃
i
,
j
∈
N
\exists\ i,j\in\mathbb N
∃ i,j∈N 且
0
≤
j
<
i
<
x
0\le j<i<x
0≤j<i<x,使得
a
i
≡
a
j
(
m
o
d
m
)
a^i\equiv a^j\pmod m
ai≡aj(modm)。故
a
i
−
j
≡
1
(
m
o
d
m
)
a^{i-j}\equiv1\pmod m
ai−j≡1(modm),由阶的定义,
i
−
j
≥
x
i-j\ge x
i−j≥x,与
0
≤
j
<
i
<
x
0\le j<i<x
0≤j<i<x 矛盾。故假设错误。
证毕。
性质5 设
b
∈
N
+
b\in\mathbb N^+
b∈N+,若
a
b
≡
1
(
m
o
d
m
)
ab\equiv1\pmod m
ab≡1(modm),则
ord
m
a
=
ord
m
b
\text{ord}_ma=\text{ord}_mb
ordma=ordmb。
证明 令
ord
m
a
=
x
\text{ord}_ma=x
ordma=x,
ord
m
b
=
y
\text{ord}_mb=y
ordmb=y,则有
a
x
≡
1
(
m
o
d
m
)
a^x\equiv1\pmod m
ax≡1(modm),
b
y
≡
1
(
m
o
d
m
)
b^y\equiv 1\pmod m
by≡1(modm)。
a
x
b
x
≡
b
x
≡
1
(
m
o
d
m
)
a^xb^x\equiv b^x\equiv1\pmod m
axbx≡bx≡1(modm),由阶的定义
x
≥
y
x\ge y
x≥y。
a
y
b
y
≡
a
y
≡
1
a^yb^y\equiv a^y\equiv 1
ayby≡ay≡1,由阶的定义,
x
≤
y
x\le y
x≤y。所以,
x
=
y
x=y
x=y。
证毕。
性质6 令
x
=
ord
m
a
x=\text{ord}_ma
x=ordma,有
t
∈
N
+
t\in\mathbb N^+
t∈N+ 则
ord
m
a
t
=
x
gcd
(
t
,
x
)
\text{ord}_ma^t=\frac{x}{\gcd(t,x)}
ordmat=gcd(t,x)x。
证明 令
ord
m
a
t
=
k
\text{ord}_ma^t=k
ordmat=k,根据阶的定义,有
a
k
t
≡
1
(
m
o
d
m
)
a^{kt}\equiv1\pmod m
akt≡1(modm)。
由性质1,
x
∣
k
t
x\mid kt
x∣kt,故
x
gcd
(
t
,
x
)
∣
t
gcd
(
t
,
x
)
k
\frac{x}{\gcd(t,x)}\mid\frac{t}{\gcd(t,x)}k
gcd(t,x)x∣gcd(t,x)tk 。根据最大公约数的性质,
x
gcd
(
t
,
x
)
⊥
t
gcd
(
t
,
x
)
\frac{x}{\gcd(t,x)}\bot\frac{t}{\gcd(t,x)}
gcd(t,x)x⊥gcd(t,x)t,所以
x
gcd
(
t
,
x
)
∣
k
\frac{x}{\gcd(t,x)}\mid k
gcd(t,x)x∣k。
根据阶的定义,
k
k
k 为满足
x
gcd
(
t
,
x
)
∣
k
\frac{x}{\gcd(t,x)}\mid k
gcd(t,x)x∣k 的最小正整数,故
k
=
x
gcd
(
t
,
x
)
k=\frac{x}{\gcd(t,x)}
k=gcd(t,x)x。
证毕。
性质7 设
w
∈
N
+
w\in\mathbb N^+
w∈N+,若
w
∣
m
w\mid m
w∣m,则
ord
w
a
∣
ord
m
a
\text{ord}_wa\mid \text{ord}_ma
ordwa∣ordma。
证明 由阶的定义,
a
o
r
d
m
a
≡
1
(
m
o
d
m
)
a^{\mathrm{ord}_ma}\equiv1\pmod m
aordma≡1(modm);因此,
a
o
r
d
m
a
=
k
m
+
1
a^{\mathrm{ord}_ma}=km+1
aordma=km+1,
k
∈
N
k\in\mathbb N
k∈N。因为
w
∣
m
w\mid m
w∣m,所以
a
o
r
d
m
a
≡
1
(
m
o
d
w
)
a^{\mathrm{ord}_ma}\equiv1\pmod w
aordma≡1(modw)。根据性质1,
ord
w
a
∣
ord
m
a
\text{ord}_wa\mid \text{ord}_ma
ordwa∣ordma。
证毕。
性质8 设
n
∈
N
+
n\in\mathbb N^+
n∈N+。若
m
⊥
n
,
a
⊥
n
m\bot n,a\bot n
m⊥n,a⊥n,则
ord
m
n
a
=
lcm
(
ord
m
a
,
ord
n
a
)
\text{ord}_{mn}a=\text{lcm}(\text{ord}_{m}a,\text{ord}_{n}a)
ordmna=lcm(ordma,ordna)。
证明 令
x
=
ord
m
n
a
x=\text{ord}_{mn}a
x=ordmna,
y
=
lcm
(
ord
m
a
,
ord
n
a
)
y=\text{lcm}(\text{ord}_{m}a,\text{ord}_{n}a)
y=lcm(ordma,ordna)。
根据阶的定义,
a
x
≡
1
(
m
o
d
m
n
)
a^x\equiv1\pmod{mn}
ax≡1(modmn),于是有
a
x
=
k
m
n
+
1
a^x=kmn+1
ax=kmn+1,
k
∈
M
k\in\mathbb M
k∈M;故
a
x
≡
1
(
m
o
d
m
)
a^x\equiv 1\pmod {m}
ax≡1(modm),
a
x
≡
1
(
m
o
d
n
)
a^x\equiv 1\pmod {n}
ax≡1(modn)。由性质1,$ \text{ord}_ma\mid x$ 且
ord
n
a
∣
x
\text{ord}_na\mid x
ordna∣x,故
lcm
(
ord
m
a
,
ord
n
a
)
∣
x
\text{lcm}(\text{ord}_{m}a,\text{ord}_{n}a)\mid x
lcm(ordma,ordna)∣x,即
y
∣
x
y\mid x
y∣x。
由最小公倍数的定义,有
o
r
d
m
a
∣
y
ord
n
a
∣
y
\mathrm{ord}_{m}a\mid y\text{ord}_{n}a\mid y
ordma∣yordna∣y。根据性质1,有
a
y
≡
1
(
m
o
d
m
)
a^y\equiv1\pmod m
ay≡1(modm) 且
a
y
≡
1
(
m
o
d
n
)
a^y\equiv1\pmod n
ay≡1(modn);令
a
y
=
k
1
m
+
1
=
k
2
n
+
1
a^y=k_1m+1=k_2n+1
ay=k1m+1=k2n+1,
k
1
,
k
2
∈
N
k_1,k_2\in\mathbb N
k1,k2∈N,即
k
1
m
=
k
2
n
k_1m=k_2n
k1m=k2n。因为
m
⊥
n
m\bot n
m⊥n,故
k
1
=
k
n
,
k
2
=
k
m
k_1=kn,k_2=km
k1=kn,k2=km,
k
∈
N
k\in\mathbb N
k∈N,所以
a
y
≡
1
(
m
o
d
m
n
)
a^y\equiv1\pmod{mn}
ay≡1(modmn)。再次根据性质1,有
o
r
d
m
n
a
∣
y
\mathrm{ord}_{mn}a\mid y
ordmna∣y,即
x
∣
y
x|y
x∣y。
综上所述,
x
=
y
x=y
x=y,即
ord
m
n
a
=
lcm
(
ord
m
a
,
ord
n
a
)
\text{ord}_{mn}a=\text{lcm}(\text{ord}_{m}a,\text{ord}_{n}a)
ordmna=lcm(ordma,ordna)。
证毕。
性质9 设
b
∈
N
+
b\in\mathbb N^+
b∈N+,若
b
⊥
m
b\bot m
b⊥m 且
o
r
d
m
a
⊥
o
r
d
m
b
\mathrm{ord}_ma\bot \mathrm{ord}_mb
ordma⊥ordmb,则
o
r
d
m
a
b
=
o
r
d
m
a
×
o
r
d
m
b
\mathrm{ord}_mab=\mathrm{ord}_ma\times \mathrm{ord}_mb
ordmab=ordma×ordmb 。
证明 令
x
=
o
r
d
m
a
x=\mathrm{ord}_ma
x=ordma,
y
=
o
r
d
m
b
y=\mathrm{ord}_mb
y=ordmb,
z
=
o
r
d
m
a
b
z=\mathrm{ord}_mab
z=ordmab。由阶的定义,有
a
x
≡
1
(
m
o
d
m
)
a^x\equiv1\pmod m
ax≡1(modm),
b
y
≡
1
(
m
o
d
m
)
b^y\equiv1\pmod m
by≡1(modm),
(
a
b
)
z
≡
1
(
m
o
d
m
)
(ab)^z\equiv1\pmod m
(ab)z≡1(modm)。
由
(
a
b
)
z
≡
1
(
m
o
d
m
)
(ab)^z\equiv1\pmod m
(ab)z≡1(modm),得
a
z
≡
1
(
m
o
d
m
)
a^z\equiv1\pmod m
az≡1(modm) 且
b
z
≡
1
(
m
o
d
m
)
b^z\equiv 1\pmod m
bz≡1(modm)。根据性质1,
x
∣
z
x\mid z
x∣z 且
y
∣
z
y\mid z
y∣z,故
l
c
m
(
x
,
y
)
∣
z
\mathrm{lcm}(x,y)\mid z
lcm(x,y)∣z。因为
o
r
d
m
a
⊥
o
r
d
m
b
\mathrm{ord}_ma\bot \mathrm{ord}_mb
ordma⊥ordmb,即
x
⊥
y
x\bot y
x⊥y;所以
l
c
m
(
x
,
y
)
=
x
y
\mathrm{lcm}(x,y)=xy
lcm(x,y)=xy,即
x
y
∣
z
xy\mid z
xy∣z。
因为
x
=
o
r
d
m
a
x=\mathrm{ord}_ma
x=ordma 且
y
=
o
r
d
m
b
y=\mathrm{ord}_mb
y=ordmb,所以
(
a
b
)
x
y
≡
1
(
m
o
d
m
)
(ab)^{xy}\equiv 1\pmod m
(ab)xy≡1(modm)。根据性质1,
z
∣
x
y
z\mid xy
z∣xy。
综上所述,
z
=
x
y
z=xy
z=xy,即
o
r
d
m
a
b
=
o
r
d
m
a
×
o
r
d
m
b
\mathrm{ord}_mab=\mathrm{ord}_ma\times \mathrm{ord}_mb
ordmab=ordma×ordmb。
证毕。
原根
原根的定义
设 g , m ∈ N + g,m\in\mathbb N^+ g,m∈N+,且 g ⊥ m g\bot m g⊥m;若 o r d m g = φ ( m ) \mathrm{ord}_mg=\varphi(m) ordmg=φ(m),则称 g g g 是模 m m m 的原根。
原根存在定理
不加证明地给出:模 m {\displaystyle m} m 有原根的充要条件是 m = 2 , 4 , p k , 2 p k m=2,4,p^k,2p^k m=2,4,pk,2pk,其中 p p p 是奇素数, k k k 是任意正整数。
原根判定定理
不加证明地给出:若 g g g 为模 m m m 的原根,则对于任意 φ ( m ) \varphi(m) φ(m) 的质因子 p p p,必有 g φ ( m ) p ≢ 1 ( m o d m ) g^{\frac{\varphi(m)}{p}}\not\equiv 1 \pmod m gpφ(m)≡1(modm)。
求所有原根
定理 设
g
g
g 为模
m
m
m 的原根,则集合
S
=
{
g
s
∣
1
≤
s
≤
φ
(
m
)
,
s
⊥
φ
(
m
)
}
S=\{g^{s} \mid 1 \leq s \leq \varphi(m),s\bot\varphi(m)\}
S={gs∣1≤s≤φ(m),s⊥φ(m)} 给出模
m
m
m 的全部原根。模
m
m
m 的原根有
φ
(
φ
(
m
)
)
\varphi(\varphi(m))
φ(φ(m)) 个。
略证 由原根的判定定理,对于任意
φ
(
m
)
\varphi(m)
φ(m) 的质因子
p
p
p,有
g
φ
(
m
)
p
≢
1
(
m
o
d
m
)
g^{\frac{\varphi(m)}{p}}\not\equiv 1 \pmod m
gpφ(m)≡1(modm);因此,
(
g
s
)
φ
(
m
)
p
≡
(
g
φ
(
m
)
)
s
p
(
m
o
d
m
)
\left(g^s\right)^{\frac{\varphi(m)}{p}}\equiv \left(g^{\varphi(m)}\right)^{\frac{s}{p}}\pmod m
(gs)pφ(m)≡(gφ(m))ps(modm)。若
gcd
(
s
,
φ
(
m
)
)
>
1
\gcd(s,\varphi(m))>1
gcd(s,φ(m))>1,则存在一个
p
p
p,使得
p
∣
s
p\mid s
p∣s;此时,
(
g
φ
(
m
)
)
s
p
≡
g
k
φ
(
m
)
(
m
o
d
m
)
\left(g^{\varphi(m)}\right)^{\frac{s}{p}}\equiv g^{k\varphi(m)}\pmod m
(gφ(m))ps≡gkφ(m)(modm),
k
∈
N
+
k\in\mathbb N^+
k∈N+;根据欧拉定理
g
φ
(
m
)
≡
1
(
m
o
d
m
)
g^{\varphi(m)}\equiv1\pmod m
gφ(m)≡1(modm)。因此,当且仅当
s
⊥
φ
(
m
)
s\bot\varphi(m)
s⊥φ(m),
g
s
g^s
gs 才为模
m
m
m 的原根。
若
s
>
φ
(
m
)
s>\varphi(m)
s>φ(m),由扩展欧拉定理,则
g
s
≡
g
s
m
o
d
φ
(
m
)
(
m
o
d
m
)
g^s\equiv g^{s\bmod \varphi(m)}\pmod m
gs≡gsmodφ(m)(modm),转化为
1
≤
s
≤
φ
(
m
)
1\le s\le \varphi(m)
1≤s≤φ(m) 的问题。
根据欧拉函数定义,满足条件
1
≤
s
≤
φ
(
m
)
,
s
⊥
φ
(
m
)
1\leq s \leq \varphi(m),s\bot\varphi(m)
1≤s≤φ(m),s⊥φ(m) 的
s
s
s 有
φ
(
φ
(
m
)
)
\varphi(\varphi(m))
φ(φ(m)) 个。根据阶的性质4,这
φ
(
φ
(
m
)
)
\varphi(\varphi(m))
φ(φ(m)) 个原根模
m
m
m 两两不同余。
可以证明,最小原根是不大于
m
4
\sqrt[4]{m}
4m 级别的。因此,不妨枚举
[
1
,
m
4
]
[1,\sqrt[4]{m}]
[1,4m] 的整数,得到最小原根
g
g
g,这样的时间是可以接受的;接着,再枚举
g
s
g^s
gs 的指数
s
s
s,若
s
s
s 与
φ
(
m
)
\varphi(m)
φ(m) 互质,则
g
s
m
o
d
m
g^s\bmod m
gsmodm 为一个原根。
51Nod 1135 原根 ↬ \looparrowright ↬
给出一个质数 P P P,找出 P P P 最小的原根。
输入
输入一个质数 P P P ( 3 ≤ P ≤ 1 0 9 ) (3\le P \le 10^9) (3≤P≤109)。
输出
输出 P P P 最小的原根。
输入样例
3
输出样例
2
分析
从
1
1
1 开始枚举可能的原根,根据原根判定定理检验:对于任意
φ
(
P
)
\varphi(P)
φ(P) 的质因子
p
p
p,有
g
φ
(
P
)
p
≢
1
(
m
o
d
P
)
g^{\frac{\varphi(P)}{p}}\not\equiv 1 \pmod P
gpφ(P)≡1(modP)。
由欧拉函数的性质,
P
P
P 为质数,故
φ
(
P
)
=
P
−
1
\varphi(P)=P-1
φ(P)=P−1。
代码
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
vector<ll>prime_factor;
ll P;
//--------------------------------
//分解质因数
void divide(ll x)
{
ll i;
for(i=2;i*i<=x;i++)
{
if(x%i==0)
{
prime_factor.push_back(i);
while(x%i==0) x/=i;
}
}
if(x>1) prime_factor.push_back(i);
}
//-----------------------------------
//-----------------------------------
//若P为质数
//φ(P)=P-1
inline ll phi(ll p) {return p-1;}
//-----------------------------------
//-----------------------------------
//快速幂
inline ll qpow_mod(ll a,ll b,ll mod)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
//------------------------------------
int main()
{
cin>>P;
divide(phi(P));
ll i,j;
for(i=1;;i++)//枚举
{
bool is=1;
//遍历P-1的所有质因子
for(j=0;j<prime_factor.size();j++)
{
if(qpow_mod(i,phi(P)/prime_factor[j],P)==1)
{
is=0;
break;
}
}
if(is)//满足条件
{
cout<<i<<endl;
return 0;
}
}
}
HDU Primitive Roots 4992 ↬ \looparrowright ↬
Problem Description
We say that integer x x x, 0 < x < n 0 < x < n 0<x<n, is a primitive root modulo n n n if and only if the minimum positive integer y y y which makes x y = 1 ( m o d n ) x^y = 1 \pmod n xy=1(modn) true is φ ( n ) φ(n) φ(n) . Here φ ( n ) φ(n) φ(n) is an arithmetic function that counts the totatives of n n n, that is, the positive integers less than or equal to n n n that are relatively prime to n n n. Write a program which given any positive integer n n n ( 2 ≤ n < 1000000 ) ( 2 \le n < 1000000) (2≤n<1000000), outputs all primitive roots of n n n in ascending order.
Input
Multi test cases.
Each line of the input contains a positive integer
n
n
n. Input is terminated by the end-of-file separator.
Output
For each n n n, outputs all primitive roots of n n n in ascending order in a single line, if there is no primitive root for n n n just print − 1 -1 −1 in a single line.
Sample Input
4
25
Sample Output
3
2 3 8 12 13 17 22 23
Idea
首先根据原根存在定理判断原根是否存在。
若原根存在,枚举
[
1
,
n
4
]
[1,\sqrt[4]{n}]
[1,4n] 的整数,得到最小原根
g
g
g;接着,再枚举
g
s
g^s
gs 的指数
s
s
s,若
s
s
s 与
φ
(
n
)
\varphi(n)
φ(n) 互质,则
g
s
m
o
d
n
g^s\bmod n
gsmodn 为一个原根;若找到的原根已经达到
φ
(
φ
(
n
)
)
\varphi(\varphi(n))
φ(φ(n)) 个,就可以停止枚举。
Code
#include<cstdio>
#include<vector>
#include<algorithm>
#define ll long long
#define N 1000002
using namespace std;
int cnt;//质数个数
bool vis[N];//vis[i]=1表示i为合数
int prime[N>>1];//质数
int phi[N];//欧拉函数
vector<int>prime_factor;//质因子
vector<int>ans;//所有模n的原根
//-------------------------------------------------------
//欧拉筛线性得到欧拉函数
void get_phi(int n)
{
phi[1]=1;
int i,j;
for(i=2;i<=n;i++)
{
if(!vis[i])
{
phi[i]=i-1;
prime[++cnt]=i;
}
for(j=1;j<=cnt&&i*prime[j]<=n;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
//-------------------------------------------------------
//-------------------------------------------------------
//快速幂
inline int qpow_mod(ll a,int b,int mod)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
//-------------------------------------------------------
//-------------------------------------------------------
//分解质因数
inline void divide(int x)
{
int i;
for(i=2;i*i<=x;i++)
{
if(x%i==0)
{
prime_factor.push_back(i);
while(x%i==0) x/=i;
}
}
if(x>1) prime_factor.push_back(x);
}
//-------------------------------------------------------
//-------------------------------------------------------
//利用原根存在定理
bool exist(int n)
{
if(n==2||n==4) return 1;
if(n%2==0) n/=2;//猜测为奇素数幂的二倍
int i;
//检验是否为奇素数的幂
for(i=2;prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
while(n%prime[i]==0) n/=prime[i];
//若n存在原根
//i为唯一质因子
return n==1;
}
}
return 0;
}
//-------------------------------------------------------
//-------------------------------------------------------
int main()
{
get_phi(1000000);//预处理1~1000000的欧拉函数
int n;
while(~scanf("%intd",&n))
{
//首先检验n是否存在原根
if(exist(n))
{
prime_factor.clear();
ans.clear();
//对phi[n]分解质因数
divide(phi[n]);
int i,j;
int g;
//---------------------------------------------------------
//找到最小原根g
for(i=1;;i++)
{
bool is=1;
if(__gcd(i,n)!=1) continue;//i不存在模n的阶
for(j=0;j<prime_factor.size();j++)
{
//--------------------------------------------------
//原根判定
//对phi[n]的所有质因子p
//i^(phi[n]/p)%n!=1;
if(qpow_mod(i,phi[n]/prime_factor[j],n)==1)
{
is=0;
break;
}
//--------------------------------------------------
}
if(is)//找到最小原根
{
g=i;
break;
}
}
//---------------------------------------------------------
//---------------------------------------------------------
//枚举指数s
//若s与phi[n]互质
//g^s为原根
int s;
ll power=1;
for(s=1;ans.size()<phi[phi[n]];s++)
{
power=power*g%n;
if(__gcd(phi[n],s)==1) ans.push_back(power);
}
sort(ans.begin(),ans.end());
//---------------------------------------------------------
for(i=0;i<ans.size();i++)
{
if(i) putchar(' ');
printf("%d",ans[i]);
}
putchar('\n');
}
else puts("-1");
}
return 0;
}