下述理论主要参考书目: 电子版pdf:算法竞赛进阶指南(p133-150)
文章目录
- 下述理论主要参考书目: [电子版pdf:算法竞赛进阶指南(p133-150)](http://www.j9p.com/down/536233.html)
- 首先补充两个前置知识:约数和最大约数有关性质,可选择性看~
- 有关素数筛的算法 [埃式 n l o g ( n ) nlog(n) nlog(n)&欧拉素数筛 o ( n ) o(n) o(n)&大区间素数筛](https://blog.csdn.net/weixin_45819197/article/details/109545970)
- 约数
- 最大公约数
- 1.gcd(a,b)=gcd(a,a-b)=gcd(b,a-b)=d;
- 2.欧几里得算法: b!=0; gcd(a,b)=gcd(b,a%b)=d;
- 欧拉函数
- φ(N)=N*(1 - 1 p 1 \displaystyle\frac{1}{p_1} p11)(1 - 1 p 2 \displaystyle\frac{1}{p_2} p21)(1 - 1 p 3 \displaystyle\frac{1}{p_3} p31)......(1 - 1 p m \displaystyle\frac{1}{p_m} pm1)
- 欧拉函数的一些性质
- 2.性质2我们知道了欧拉函数是积性函数(PS:积性函数:对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数)
- 3.p 为质数,若p|n 且 p 2 p^2 p2|n,则φ(n)= φ ( n p ) ∗ p φ(\displaystyle\frac{n}{p})*p φ(pn)∗p;
- 4.p 为质数,若p|n 且 p 2 p^2 p2不n整除,则φ(n)= φ ( n p ) ∗ ( p − 1 ) φ(\displaystyle\frac{n}{p})*(p-1) φ(pn)∗(p−1);
- 5. ∑ d ∣ n φ ( d ) = n \sum_{d|n}φ(d)=n ∑d∣nφ(d)=n
- 同余
- 同余的基本性质
- 性质一: 如果a ≡ \equiv ≡b(mod m),c ≡ \equiv ≡d(mod m).那么( a ± c a\pm c a±c) ≡ \equiv ≡( b ± d b \pm d b±d) (mod m)。
- 性质二:如果a ≡ \equiv ≡b(mod m),c ≡ \equiv ≡d(mod m).那么( a ∗ c a*c a∗c) ≡ \equiv ≡( b ∗ d b*d b∗d) (mod m)。
- 性质三: 如果ac ≡ \equiv ≡bc(mod m), 且 gcd(c,m)=1(c和m互质) , 则有a ≡ \equiv ≡b(mod m)。
- 性质四:若ac≡bd,c≡d(mod m),且gcd(c,m)=1,得到a≡b(mod m)。
- 同余类与剩余系
- 费马小定理 & 欧拉定理
- 趁热打铁来一道关于BSBG的算法题(依据费马下定理)
- [Discrete Logging POJ - 2417 ](https://vjudge.net/problem/POJ-2417)
- 欧拉定理的推论
- 最小正整数 x 0 x_0 x0
- 欧拉的指数循环节
- 其他理论
- 来看一到题:[余数之和](https://www.acwing.com/problem/content/201/)
首先补充两个前置知识:约数和最大约数有关性质,可选择性看~
有关素数筛的算法 埃式 n l o g ( n ) nlog(n) nlog(n)&欧拉素数筛 o ( n ) o(n) o(n)&大区间素数筛
约数
最大公约数
1.gcd(a,b)=gcd(a,a-b)=gcd(b,a-b)=d;
2.欧几里得算法: b!=0; gcd(a,b)=gcd(b,a%b)=d;
(ps:其实这里有个一般性的结论:gcd(m, n n n)=gcd(m, k ∗ m + r 1 k*m+r_1 k∗m+r1),n= k ∗ m + r 1 k*m+r_1 k∗m+r1,k为整数,0<= r 1 r_1 r1<m)
1.证明:d|a 且 d|b 那么d| (a-b) 得证
2.证明:a<b 显然易得
a>=b: 令 a= q ∗ b q*b q∗b+r;
由于d|a d| ( q ∗ b ) (q*b) (q∗b)
那么易得 d|(a- q ∗ b q*b q∗b) 即得d|r
又r=a mod b ,所以gcd(a,b)=gcd(b,a%mod);
欧拉函数
φ(N)=N*(1 - 1 p 1 \displaystyle\frac{1}{p_1} p11)(1 - 1 p 2 \displaystyle\frac{1}{p_2} p21)(1 - 1 p 3 \displaystyle\frac{1}{p_3} p31)…(1 - 1 p m \displaystyle\frac{1}{p_m} pm1)
证明:
具体用到了容斥原理:
φ(N)=N - ( N p 1 \displaystyle\frac{N}{p_1} p1N + N p 2 \displaystyle\frac{N}{p_2} p2N + N p 3 \displaystyle\frac{N}{p_3} p3N + N p 4 \displaystyle\frac{N}{p_4} p4N- N p 1 p 2 \displaystyle\frac{N}{p_1p_2} p1p2N - N p 2 p 3 \displaystyle\frac{N}{p_2p_3} p2p3N- N p 1 p 3 \displaystyle\frac{N}{p_1p_3} p1p3N - N p 1 p 4 \displaystyle\frac{N}{p_1p_4} p1p4N - N p 2 p 4 \displaystyle\frac{N}{p_2p_4} p2p4N - N p 3 p 4 \displaystyle\frac{N}{p_3p_4} p3p4N + N p 1 p 2 p 3 \displaystyle\frac{N}{p_1p_2p_3} p1p2p3N + N p 1 p 2 p 4 \displaystyle\frac{N}{p_1p_2p_4} p1p2p4N…-…+…-… N p 1 p 2 p 3 . . . . . . p m \displaystyle\frac{N}{p_1p_2p_3......p_m} p1p2p3......pmN)
(ps:分式这小东西麻烦啦啊aaa…)
上面的式子因式分解就得到了:
即是: φ(N)=N*(1 - 1 p 1 \displaystyle\frac{1}{p_1} p11)(1 - 1 p 2 \displaystyle\frac{1}{p_2} p21)(1 - 1 p 3 \displaystyle\frac{1}{p_3} p31)…(1 - 1 p m \displaystyle\frac{1}{p_m} pm1)
欧拉函数的一些性质
2.性质2我们知道了欧拉函数是积性函数(PS:积性函数:对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数)
3.p 为质数,若p|n 且 p 2 p^2 p2|n,则φ(n)= φ ( n p ) ∗ p φ(\displaystyle\frac{n}{p})*p φ(pn)∗p;
4.p 为质数,若p|n 且 p 2 p^2 p2不n整除,则φ(n)= φ ( n p ) ∗ ( p − 1 ) φ(\displaystyle\frac{n}{p})*(p-1) φ(pn)∗(p−1);
5. ∑ d ∣ n φ ( d ) = n \sum_{d|n}φ(d)=n ∑d∣nφ(d)=n
证明:
1.由于gcd(n,x)=gcd(n,n-x)=1,所以与n互质的数是"成对"的出现。进而n+(n-x)=n. 就得出了
2.性质2就很显然了,根据欧拉函数的公式 φ(N). a,b互质,所以分解质因数没有一样的,根据欧拉函数就可以将 φ(a) φ(b)合并得出了φ(N)。
所以欧拉函数是积性函数
3.用到了 φ(N)=N ∗ * ∗ (1 - 1 p 1 \displaystyle\frac{1}{p_1} p11)(1 - 1 p 2 \displaystyle\frac{1}{p_2} p21)(1 - 1 p 3 \displaystyle\frac{1}{p_3} p31)…(1 - 1 p m \displaystyle\frac{1}{p_m} pm1)
p 2 p^2 p2|n主要告诉咱们N分解后p的质因数个数不少于2. 所以 N p \displaystyle\frac{N}{p} pN分解后的质因数还有p.
φ( N N N)和φ( N p \displaystyle\frac{N}{p} pN)的欧拉函数表达式中(1 - 1 p i \displaystyle\frac{1}{p_i} pi1)全都一样,只是一个是N和 N p \displaystyle\frac{N}{p} pN。
所以就得出了φ(N)= φ ( N p ) ∗ p φ(\displaystyle\frac{N}{p})*p φ(pN)∗p;
4.是同理3的证明方法。
5.性质5: f ( n ) = ∑ d ∣ n φ ( d ) = n f(n)=\sum_{d|n}φ(d)=n f(n)=∑d∣nφ(d)=n 证明比较难了,首先得证明 f ( n ) f(n) f(n)是积性函数. f ( n ) f(n) f(n)积性函数证明:其实有点显然了, 若n,m互质,出发点仍然是质因数分解考虑. 举个栗子:n=6, m=35, n,m互质.
n中的d:1,2,3. m中的d:1,5,7. 然后我们知道欧拉函数 φ(N)是个积性函数(见性质2)。
( 1 , 2 , 3 ) ∗ ( 1 , 5 , 7 ) (1,2,3)*(1,5,7) (1,2,3)∗(1,5,7)的分解得出集合d全是能整除 n ∗ m n*m n∗m,不多不少。 ps: ( 1 , 2 , 3 ) ∗ ( 1 , 5 , 7 ) (1,2,3)*(1,5,7) (1,2,3)∗(1,5,7) 得到的d集合(1,5,7,2,10,14,3,15,21).
所以就知道了嘛: n,m互质 那么: f ( n ∗ m ) = f ( n ) f ( m ) f(n*m)=f(n)f(m) f(n∗m)=f(n)f(m) 得证: f ( n ) f(n) f(n)是积性函数
ps:φ(1)=1
同余
定义:若整数a和整数b除以正整数m的余数相等,则称a,b模m同余。记为a
≡
\equiv
≡ b(mod m)。
eg:10
≡
\equiv
≡ 24(mod 7) 同余数3.
同余的基本性质
在写性质之前,先得有种这样的思路。
a=
p
∗
m
p*m
p∗m+
r
1
r_1
r1
b=
q
∗
m
q*m
q∗m+
r
2
r_2
r2
如果a
≡
\equiv
≡b(mod m),那么
r
1
r_1
r1=
r
2
r_2
r2。
性质一: 如果a ≡ \equiv ≡b(mod m),c ≡ \equiv ≡d(mod m).那么( a ± c a\pm c a±c) ≡ \equiv ≡( b ± d b \pm d b±d) (mod m)。
(ps:从 r 1 r_1 r1 和 r 2 r_2 r2这方面思考)。
性质二:如果a ≡ \equiv ≡b(mod m),c ≡ \equiv ≡d(mod m).那么( a ∗ c a*c a∗c) ≡ \equiv ≡( b ∗ d b*d b∗d) (mod m)。
证明: 首先从已知得到a和b的余数是
r
1
r_1
r1,c和d的余数是
r
2
r_2
r2.
a=
p
∗
m
p*m
p∗m+
r
1
r_1
r1, c=
q
∗
m
q*m
q∗m+
r
2
r_2
r2
然后呢
a
∗
c
a*c
a∗c=
p
∗
q
∗
m
p*q*m
p∗q∗m +
(
r
1
+
r
2
)
∗
m
(r_1+r_2)*m
(r1+r2)∗m +
r
1
∗
r
2
r_1*r_2
r1∗r2.
对于
b
∗
d
b*d
b∗d同理的,那些(
p
∗
q
∗
m
p*q*m
p∗q∗m +
(
r
1
+
r
2
)
∗
m
(r_1+r_2)*m
(r1+r2)∗m)能被整除的不用管它,然后后面的尾巴都是
r
1
∗
r
2
r_1*r_2
r1∗r2.所以得以证明。
性质三: 如果ac ≡ \equiv ≡bc(mod m), 且 gcd(c,m)=1(c和m互质) , 则有a ≡ \equiv ≡b(mod m)。
这条性质很重要,反复品味。
证明: 对于ac
≡
\equiv
≡bc(mod m)有ac=
p
∗
m
p*m
p∗m+
r
1
r_1
r1,bc=
q
∗
m
q*m
q∗m+
r
1
r_1
r1。
所以ac-
p
∗
m
p*m
p∗m=bc-
q
∗
m
q*m
q∗m.
得到:
(
a
−
b
)
∗
c
(a-b)*c
(a−b)∗c=
(
p
−
q
)
∗
m
(p-q)*m
(p−q)∗m。
再可得到
(
a
−
b
)
∗
c
(a-b)*c
(a−b)∗c中能被m整除。
然后根据算术基本定理:n=
p
1
c
1
p_{1}^{c_1}
p1c1
p
2
c
2
p_{2}^{c_2}
p2c2
p
3
c
3
p_{3}^{c_3}
p3c3
p
4
c
4
p_{4}^{c_4}
p4c4…
p
m
c
m
p_{m}^{c_m}
pmcm
由于gcd(c,m)=1, m不在c中,那么m只能在
a
−
b
a-b
a−b中。(即是
a
−
b
a-b
a−b=
k
∗
m
k*m
k∗m)
用符号表示:m|(a-b).
a=
p
∗
m
p*m
p∗m+
r
1
r_1
r1
b=
q
∗
m
q*m
q∗m+
r
2
r_2
r2
a-b=
(
p
−
q
)
∗
m
(p-q)*m
(p−q)∗m+
(
r
1
−
r
2
)
(r_1-r_2)
(r1−r2)
能被m整除,所以
r
1
r_1
r1=
r
2
r_2
r2
这就说明了a和b的余数都是
r
1
r_1
r1。 所以a
≡
\equiv
≡b(mod m)。
性质四:若ac≡bd,c≡d(mod m),且gcd(c,m)=1,得到a≡b(mod m)。
(ps:其实性质三是性质四的特殊情况,c=d )
证明: 首先c与d的余数相等,记为
r
1
r_1
r1,
又因为gcd(c,m)=1;
所以
r
1
r_1
r1=1
所以我们得出了gcd(d,m)=1.
a=
p
∗
m
p*m
p∗m+
r
2
r_2
r2
c=
q
∗
m
q*m
q∗m+
1
1
1
b=
k
∗
m
k*m
k∗m+
r
3
r_3
r3
ac=(
p
∗
q
∗
m
p*q*m
p∗q∗m) + (
p
∗
m
p*m
p∗m) + (
q
∗
m
∗
r
1
q*m*r_1
q∗m∗r1) +
r
2
r_2
r2
bd=…+
r
3
r_3
r3
由于ac与bd余数相等,所以
r
2
=
r
3
r_2=r_3
r2=r3。
所以a≡b(mod m)。
同余类与剩余系
gcd( a ∗ b a*b a∗b,m)=1; gcd( a ∗ b a*b a∗b,m)=gcd( ( a ∗ b ) (a*b) (a∗b)%m,m)=1. (ps:见最大公约数性质二)
所以 ( a ∗ b ) (a*b) (a∗b)%m 与 m互质。 所以得出了简化剩余系关于模m乘法封闭。
(ps:这个关系怎么理解呢?对于所有的a,gcd(a,m)=1,那么gcd(a%m,m)=1,即是所有a都能映射到m的简化剩余系中)
费马小定理 & 欧拉定理
1.费马小定理:若p是质数,则对于任意整数a,有
a
p
≡
a
a^p\equiv a
ap≡a(mod p)。
2.欧拉定理:若正整数a,n互质,则
a
φ
(
n
)
≡
1
a^{φ(n)}\equiv 1
aφ(n)≡1(mod n).
ps:我个人一般会写成
a
φ
(
p
)
≡
1
a^{φ(p)}\equiv 1
aφ(p)≡1(mod p).
证明:
设n的简化剩余系为{
a
1
‾
\overline{a_1}
a1,
a
2
‾
\overline{a_2}
a2,
a
3
‾
\overline{a_3}
a3,
⋯
\cdots
⋯
a
φ
(
n
)
‾
\overline{a_{φ(n)}}
aφ(n)}。对于
∀
a
i
,
a
j
\forall a_i,a_j
∀ai,aj,若
a
∗
a
i
≡
a
∗
a
j
a*a_i\equiv a*a_j
a∗ai≡a∗aj(mod n)。
根据同余性质三的结论(如果ac
≡
\equiv
≡bc(mod m), 且 gcd(c,m)=1(c和m互质) , 则有a
≡
\equiv
≡b(mod m)。) 可知道
a
i
≡
a
j
a_i\equiv a_j
ai≡aj (mod n)又因为
a
i
,
a
j
∈
(
1
,
n
)
a_i,a_j\in(1,n)
ai,aj∈(1,n),所以
a
i
≠
a
j
a_i\neq a_j
ai=aj。
这个证明有什么用呢?意味着若
a
i
≠
a
j
a_i \neq a_j
ai=aj,则
(
a
∗
a
i
)
(a*a_i)
(a∗ai)%n和
(
a
∗
a
j
)
(a*a_j)
(a∗aj)%n不等。
那么
a
∗
a
i
a*a_i
a∗ai等一系列是一一对应的。
因此,集合{
a
1
‾
\overline{a_1}
a1,
a
2
‾
\overline{a_2}
a2,
a
3
‾
\overline{a_3}
a3,
⋯
\cdots
⋯
a
φ
(
n
)
‾
\overline{a_{φ(n)}}
aφ(n)}与集合{
a
a
1
‾
\overline{aa_1}
aa1,
a
a
2
‾
\overline{aa_2}
aa2,
a
a
3
‾
\overline{aa_3}
aa3,
⋯
\cdots
⋯
a
a
φ
(
n
)
‾
\overline{aa_{φ(n)}}
aaφ(n)}都能表示n的简化剩余系。
所以我们得出了这样一个东东…
a
φ
(
n
)
a
1
a
2
a
3
⋯
a
φ
(
n
)
≡
(
a
a
1
)
(
a
a
2
)
(
a
a
3
)
⋯
a
φ
(
n
)
a^{φ(n)}a_1a_2a_3\cdots a_{φ(n)}\equiv (aa_1)(aa_2)(aa_3)\cdots a_{φ(n)}
aφ(n)a1a2a3⋯aφ(n)≡(aa1)(aa2)(aa3)⋯aφ(n)
(
a
a
1
)
(
a
a
2
)
(
a
a
3
)
⋯
a
φ
(
n
)
≡
a
1
a
2
a
3
⋯
a
φ
(
n
)
(aa_1)(aa_2)(aa_3)\cdots a_{φ(n)}\equiv a_1a_2a_3\cdots a_{φ(n)}
(aa1)(aa2)(aa3)⋯aφ(n)≡a1a2a3⋯aφ(n)(mod n)
a
a
1
=
p
1
∗
m
aa_1=p_1*m
aa1=p1∗m+
r
i
r_i
ri,
a
a
2
=
p
2
∗
m
aa_2=p_2*m
aa2=p2∗m+
r
j
r_j
rj,
a
a
3
=
p
3
∗
m
aa_3=p_3*m
aa3=p3∗m+
r
k
r_k
rk,然后像这样所有的
a
a
s
aa_s
aas的余数
r
i
,
r
j
,
⋯
r
k
r_i,r_j,\cdots r_k
ri,rj,⋯rk组成的集合就是n的简化剩余系(ps:用到了上面证明的两个集合一一对应的性质,我相信您能看到这里对同余的理解应该很清楚了)就得出了上面的等式。
结合两个等式
a
φ
(
n
)
a
1
a
2
a
3
⋯
a
φ
(
n
)
≡
a
1
a
2
a
3
⋯
a
φ
(
n
)
a^{φ(n)}a_1a_2a_3\cdots a_{φ(n)}\equiv a_1a_2a_3\cdots a_{φ(n)}
aφ(n)a1a2a3⋯aφ(n)≡a1a2a3⋯aφ(n)(mod n)
a
1
a
2
a
3
⋯
a
φ
(
n
)
a_1a_2a_3\cdots a_{φ(n)}
a1a2a3⋯aφ(n)与n互质(根据同余性质三)
得出了
a
φ
(
n
)
≡
1
a^{φ(n)} \equiv 1
aφ(n)≡1(mod n)
在上述中我们的前提是a与n是互质的。故我们证明了欧拉定理。
如果n是质数,那么φ(n)=n-1。 在欧拉定理的基础上左右乘以a,得到
a
n
≡
a
a^n\equiv a
an≡a(mod n)
即证明了费马小定理
趁热打铁来一道关于BSBG的算法题(依据费马下定理)
Discrete Logging POJ - 2417
问题: 给定
a
,
b
,
p
,
a,b,p,
a,b,p,求最小非负整数x,满足
a
x
≡
b
a^x\equiv b
ax≡b(mod
p
p
p)
p是质数。
令
x
=
i
∗
m
−
j
,
x=i*m -j,
x=i∗m−j,
m
=
⌈
p
⌉
m=⌈\sqrt{p}⌉
m=⌈p⌉, 所以
a
i
m
−
j
≡
b
a^{im-j}\equiv b
aim−j≡b(mod p)
左右边同乘以
a
j
a^j
aj,得到:
a
i
m
≡
b
a
j
a^{im}\equiv ba^j
aim≡baj(mod p)
然后就可以枚举i和j了。
首先从
[
0
,
m
]
[0,m]
[0,m]枚举j,将得到的b
a
j
a^j
aj的值存入hash值。
然后,从
[
1
−
m
]
[1-m]
[1−m]枚举
i
i
i,计算
a
i
m
a^{im}
aim,查表,如果有值与之相等,则得到的
i
m
−
j
im-j
im−j是最小值.
然后最小的非负数整数x若存在一定在1-p 区间内。
注意事项:
1.为什么最小的非负数整数x若存在一定在
[
1
,
p
]
[1,p]
[1,p] 区间内
因为费马小定理:
a
p
≡
a
a^p\equiv a
ap≡a(mod p) 进而得出
a
p
−
1
≡
1
a^{p-1}\equiv 1
ap−1≡1(mod p)
x=k*(p-1)+r. 1<r<p-1
所以:
a
x
≡
r
a^x\equiv r
ax≡r(mod
p
p
p)
这说明了什么呢,一个大于等于p的x,总能在r
∈
[
1
,
p
−
1
]
\in [1,p-1]
∈[1,p−1],找出r。
2.为什么m要取
⌈
n
⌉
⌈\sqrt{n}⌉
⌈n⌉就可以?
因为是枚举嘛,开根号的时间复杂度是多少的。
3.一点j点可能会被覆盖呀??对没错。枚举j时出来的值是有可能重复,那么在map就会再次刷新,
然后若是刷新啦,j刷新值会比原来值更大(ps:在代码中解释会更直观)。j值越大,得到的x越小(
x
=
i
∗
m
−
j
x=i*m -j
x=i∗m−j),也是我们希望的。
4.关于枚举i,j区间的问题:
为什么从0−m枚举j,而从1−m枚举i? i不能为0,否则im−j有可能出现负数的情况.
hmmm 其实枚举i,j的区间并不是一定的。
依据:
x
=
i
∗
m
−
j
x=i*m -j
x=i∗m−j
还能枚举有:
i
∈
[
1
,
m
]
i\in [1,m]
i∈[1,m] ,
j
∈
[
1
,
m
]
j\in [1,m]
j∈[1,m]
参考资料:BSGS算法 学习笔记
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
ll gcd(ll a,ll b){ return b? gcd(b,a%b):a;}
//const int N=2e5+10;
const ll mod=1e9+7;
using namespace std;
ll read(){
ll s = 0, f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)) s = (s << 3) + (s << 1) + (ch ^ 48), ch = getchar();
return s * f;
}
ll a,b,p;
ll qpow(ll x,ll y){
ll ans=1;
while(y){
if(y&1){
ans=(ans*x)%p;
}
x=(x*x)%p;
y>>=1;
}
return ans;
}
ll x;
map<ll,int> mp;
void solve(){
// cout<<qpow(2,10)<<endl;
while(scanf("%lld %lld %lld",&p,&a,&b)!=EOF){
a%=p;
if(a==0 and b==0) {
printf("%d\n",1);
return ;
}
if(a==0)
{
printf("no solution\n");
return ;
}
//注意一个小细节,就是在快速幂中是p哦,别写成了mod啦,一个小小的坑~
ll m=ceil(sqrt(p));
mp.clear();
ll ans=b%p;
//枚举区间i:1-m
for(int i=1;i<=m;i++){
ans=ans*a%p;
mp[ans]=i;
// cout<<ans<<" "<<(i+1)<<endl;
}
ans=1;
int flag=0;
ll t=qpow(a,m);
// ll top=p/m+1;
for(int i=1;i<=m;i++){
ans=ans*t%p;
if(mp[ans]){
// cout<<(i*m-mp[ans]+p)%p<<endl;
printf("%lld\n",(i*m-mp[ans]+p)%p);
flag=1;
break;
}
}
if(!flag) printf("no solution\n");
// cout<<"no solution"<<endl;
}
}
int main (){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
solve();
return 0;
}
欧拉定理的推论
最小正整数 x 0 x_0 x0
欧拉的指数循环节
其他理论
1. i在区间[x,g(x)]内, ⌊ k / i ⌋ \lfloor k/i \rfloor ⌊k/i⌋ 的值都相等。
说明:
求出i的一段连续区间使得: ⌊ k / i ⌋ \lfloor k/i \rfloor ⌊k/i⌋ 是个定值。 eg: k=33,i=10; ⌊ 33 / 10 ⌋ \lfloor 33/10 \rfloor ⌊33/10⌋=3; 但是呢? ⌊ 33 / 8 ⌋ \lfloor 33/8 \rfloor ⌊33/8⌋=3; 满足 ⌊ 33 / 9 ⌋ \lfloor 33/9 \rfloor ⌊33/9⌋=3; 满足 ⌊ 33 / 11 ⌋ \lfloor 33/11 \rfloor ⌊33/11⌋=3; 满足 ⌊ 33 / 12 ⌋ \lfloor 33/12 \rfloor ⌊33/12⌋=2; 不满足 所以他的一段连续的区间是:[8,11]。 i在[8,11]内, ⌊ k / i ⌋ \lfloor k/i \rfloor ⌊k/i⌋是个定值。
证明:
由于g(x)>=x,所以i在这个区间内是个定值。
来看一到题:余数之和
题意很简单:
这里就用上了该结论。
大概讲一下写代码的思路。
我们知道一个N的正因数个数不超过2* sqrt(N).
(ps:a<b
a
∗
b
a*b
a∗b=N 那么a<sqrt(n) 和 b>sqrt(n) 所以显而易见)
知道了这个就可以说明了 i在[1,N]内
⌊
N
/
i
⌋
\lfloor N/i \rfloor
⌊N/i⌋ 值不同的个数不超过
2
∗
N
2* \sqrt{N}
2∗N.
然后就知道了有不超过2* sqrt(N)个的区间。时间复杂度在O(
N
\sqrt{N}
N);
AC代码:
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
ll gcd(ll a,ll b){ return b? gcd(b,a%b):a;}
const int N=2e5+10;
const ll mod=1e9+7;
ll read(){
ll s = 0, f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)) s = (s << 3) + (s << 1) + (ch ^ 48), ch = getchar();
return s * f;
}
using namespace std;
ll n,k;
ll sum=0;
void solve(){
n=read();k=read();
sum=n*k;
ll x=1;
ll y;
ll cnt;
while(x<=n){
if(k/x !=0)
y=k/(k/x);
else y=n;
cnt=y-x+1;
if(y<=n)
sum-= (k/x)*cnt*(x+y)/2;
else {
sum-=(k/x)*(n-x+1)*(x+n)/2;
}
x=y+1;
}
cout<< sum<<endl;
}
int main (){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
solve();
// while(1);
return 0;
}
参考博客:
同余
Discrete Logging
BSGS算法