昨天和今天的模拟赛总结就没有记录了。
数学(超级基础的)
一、质数:
1.试除法判断质数:
bool is_prime(int a) {
if (a <= 1) return false;
for (int i = 2; i <= a / i; i++)
if (a % i == 0) return false;
return true;
}
2.分解质因数:
void divide(int x) {
for (int i = 2; i <= x / i; i++) {
int p = 0;
if (x % i == 0) {
while (x % i == 0) {
x /= i;
p++;
}
printf("%d %d\n", i, p);
}
}
if (x != 1) printf("%d %d\n", x, 1);
printf("\n");
}
3.筛质数:
//埃氏筛
int get_primes() {
int sum = 0;
for (int i = 2; i <= n; i++) {
if (!st[i]) {
sum++;
for (int j = i + i; j <= n / i; j += i)
st[i * j] = 1;
}
}
return sum;
}
//线性筛
int get_primes() {
for (int i = 2; i <= n; i++) {
if (!st[i]) primes[++cnt] = i;
for (int j = 1; primes[j] <= n / i; i++) {
st[primes[j] * i] = 1;
if (i % primes[j] == 0) break;
}
}
return cnt;
}
二、约数
1.约数个数:
因为:
N
=
p
1
a
1
∗
p
2
a
2
∗
p
3
a
3
∗
p
4
a
5
∗
.
.
.
∗
p
k
a
k
N = p_1^{a_1} * p_2^{a_2} *p_3^{a_3} *p_4^{a_5} *...*p_k^{a_k}
N=p1a1∗p2a2∗p3a3∗p4a5∗...∗pkak
所以:
a
n
s
=
(
a
1
+
1
)
∗
(
a
2
+
1
)
∗
(
a
3
+
1
)
∗
.
.
.
∗
(
a
k
+
1
)
ans = (a_1 + 1) * (a_2 + 1) * (a_3 + 1) * ...* (a_k + 1)
ans=(a1+1)∗(a2+1)∗(a3+1)∗...∗(ak+1)
证明:
因为根据算数基本定理:每个数的因式分解是唯一的,所以
n
n
n 的约数就跟
a
i
a_i
ai 的选法相对应。由于
a
i
a_i
ai 不同, 那么约数
d
d
d 就不同。
a
1
a_1
a1 一共有
0
−
a
1
0 - a_1
0−a1 种取法
a
2
a_2
a2 一共有
0
−
a
2
0 - a_2
0−a2 种取法
a
3
a_3
a3 一共有
0
−
a
3
0 - a_3
0−a3 种取法
a
k
a_k
ak 一共有
0
−
a
k
0 - a_k
0−ak 种取法
根据乘法原理,一共有
a
n
s
ans
ans 个约数
unordered_map<int, int> primes;
for (int i = 2; i <= x / i; i ++ )
while (x % i == 0)
{
x /= i;
primes[i] ++ ;
}
if (x > 1) primes[x] ++ ;
这里使用unordered_map来存储是为了处理 n n n 个数的乘积的约数个数。
2.约数之和:
N
=
p
1
a
1
∗
p
2
a
2
∗
p
3
a
3
∗
p
4
a
5
∗
.
.
.
∗
p
k
a
k
N = p_1^{a_1} * p_2^{a_2} *p_3^{a_3} *p_4^{a_5} *...*p_k^{a_k}
N=p1a1∗p2a2∗p3a3∗p4a5∗...∗pkak
a
n
s
=
(
p
1
0
+
p
1
1
+
.
.
.
+
p
1
a
1
)
∗
(
p
2
0
+
p
2
1
+
.
.
.
+
p
2
a
2
)
∗
.
.
.
∗
(
p
k
0
+
p
k
1
+
.
.
.
+
p
k
a
k
)
ans = (p_1^0 + p_1^1 +...+ p_1^{a_1}) * (p_2^0 + p_2^1 +...+ p_2^{a_2}) *...* (p_k^0 + p_k^1 +...+ p_k^{a_k})
ans=(p10+p11+...+p1a1)∗(p20+p21+...+p2a2)∗...∗(pk0+pk1+...+pkak)
证明:展开就好了。
3.最大公约数:
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}