现有同余方程
ax≡b(mod p)
a
x
≡
b
(
m
o
d
p
)
其中 (a,p)=1 ( a , p ) = 1
如果暴力枚举 x x 的话,根据欧拉定理
效率是 O(p) O ( p ) 的
现在我们考虑分块,设 m=⌈p–√⌉,1≤j≤m m = ⌈ p ⌉ , 1 ≤ j ≤ m
那么原式可以表示为
aim−j≡b(mod p)
a
i
m
−
j
≡
b
(
m
o
d
p
)
即
aim≡baj(mod p)
a
i
m
≡
b
a
j
(
m
o
d
p
)
我们可以把 baj b a j 的值存储下来,枚举 i i 的时候询问是否存在这样一个,这样就可以做到 O(p–√) O ( p ) 了
如果 (a,p)>1 ( a , p ) > 1 ,这个方法就行不通了,因为 aim≡baj(mod p) a i m ≡ b a j ( m o d p ) 推回 aim−j≡b(mod p) a i m − j ≡ b ( m o d p ) 时需要两端同除以 aj a j ,而 gcd(a,p)>1 g c d ( a , p ) > 1 时就不能这样做了.
考虑对 a,b,p a , b , p 进行处理,设 g=(a,p) g = ( a , p ) ,那么
ax−1(ag)≡bg(mod pg)
a
x
−
1
(
a
g
)
≡
b
g
(
m
o
d
p
g
)
ax−1≡bg(ag)−1(mod pg)
a
x
−
1
≡
b
g
(
a
g
)
−
1
(
m
o
d
p
g
)
新的 b b 就是
新的 p p 就是
不断如此进行操作,记录最终操作次数,答案就是最后 a,b,p a , b , p 的答案加上操作次数,此外我们还需要暴力检验小于等于操作次数的答案
Code(bzoj2480)