Skip to content

Commit

Permalink
Mobius table; Multiplicative calculator; dirichlet presum; pair sqrt …
Browse files Browse the repository at this point in the history
…decomposition
  • Loading branch information
old-yan committed Jul 3, 2024
1 parent b058269 commit 88b068b
Show file tree
Hide file tree
Showing 52 changed files with 2,290 additions and 216 deletions.
11 changes: 0 additions & 11 deletions DS/GlobalHashMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,6 @@ namespace OY {
if constexpr (MakeRecord) m_recs.push_back(i);
return {m_pool + i, true};
}
bool erase(const KeyType &key) {
size_type ha = Moder<BUFFER>()(Hash<KeyType>()(key)), i = ha;
while (m_occupied[i]) {
if (key == m_pool[i].m_key) {
m_occupied[i] = false, m_size--;
return true;
}
i = i != BUFFER - 1 ? i + 1 : 0;
}
return false;
}
node *find(const KeyType &key) const {
size_type ha = Moder<BUFFER>()(Hash<KeyType>()(key)), i = ha;
while (m_occupied[i]) {
Expand Down
26 changes: 5 additions & 21 deletions DS/GlobalHashMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,7 @@

当键值已存在时,返回已存在的结点位置,且视为插入失败。

#### 8.删除(erase)

1. 数据类型

输入参数 `const KeyType &key` ,表示要删除的键值。

返回类型 `bool` ,表示是否删除成功。

2. 时间复杂度

均摊 $O(1)$ 。

3. 备注

当键值不存在时,视为删除失败。

#### 9.查询(find)
#### 8.查询(find)

1. 数据类型

Expand All @@ -165,7 +149,7 @@

当键值不存在时,返回空结点。

#### 10.插入否则赋值(insert_or_assign)
#### 9.插入否则赋值(insert_or_assign)

1. 数据类型

Expand All @@ -185,7 +169,7 @@

本方法仅当表类型为 `UnorderedMap` 时使用。

#### 11.插入否则忽略(insert_or_ignore)
#### 10.插入否则忽略(insert_or_ignore)

1. 数据类型

Expand All @@ -205,7 +189,7 @@

本方法仅当表类型为 `UnorderedMap` 时使用。

#### 12.获取映射值(get)
#### 11.获取映射值(get)

1. 数据类型

Expand All @@ -227,7 +211,7 @@

本方法仅当表类型为 `UnorderedMap` 时使用。

#### 13.获取映射值(get)
#### 12.获取映射值(get)

1. 数据类型

Expand Down
23 changes: 12 additions & 11 deletions DS/WTree.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
1. [#130. 树状数组 1 :单点修改,区间查询](https://loj.ac/p/130)
2. [#131. 树状数组 2 :区间修改,单点查询](https://loj.ac/p/131)
3. [P1972 [SDOI2009] HH的项链](https://www.luogu.com.cn/problem/P1972)
4. [P3368 【模板】树状数组 2](https://www.luogu.com.cn/problem/P3368)
5. [P3374 【模板】树状数组 1](https://www.luogu.com.cn/problem/P3374)
6. [P4145 上帝造题的七分钟 2 / 花神游历各国](https://www.luogu.com.cn/problem/P4145)
7. [P4178 Tree](https://www.luogu.com.cn/problem/P4178)
8. [P5057 [CQOI2006] 简单题](https://www.luogu.com.cn/problem/P5057)
9. [Point Add Range Sum](https://judge.yosupo.jp/problem/point_add_range_sum)(https://github.com/yosupo06/library-checker-problems/issues/20)
10. [Rectangle Sum](https://judge.yosupo.jp/problem/rectangle_sum)(https://github.com/yosupo06/library-checker-problems/issues/118)
11. [Vertex Add Path Sum](https://judge.yosupo.jp/problem/vertex_add_path_sum)(https://github.com/yosupo06/library-checker-problems/issues/125)
12. [Vertex Add Subtree Sum](https://judge.yosupo.jp/problem/vertex_add_subtree_sum)(https://github.com/yosupo06/library-checker-problems/issues/167)
13. [Static Range Count Distinct](https://judge.yosupo.jp/problem/static_range_count_distinct)(https://github.com/yosupo06/library-checker-problems/issues/770)
14. [Rectangle Add Point Get](https://judge.yosupo.jp/problem/rectangle_add_point_get)(https://github.com/yosupo06/library-checker-problems/issues/994)
4. [P3312 [SDOI2014] 数表](https://www.luogu.com.cn/problem/P3312)
5. [P3368 【模板】树状数组 2](https://www.luogu.com.cn/problem/P3368)
6. [P3374 【模板】树状数组 1](https://www.luogu.com.cn/problem/P3374)
7. [P4145 上帝造题的七分钟 2 / 花神游历各国](https://www.luogu.com.cn/problem/P4145)
8. [P4178 Tree](https://www.luogu.com.cn/problem/P4178)
9. [P5057 [CQOI2006] 简单题](https://www.luogu.com.cn/problem/P5057)
10. [Point Add Range Sum](https://judge.yosupo.jp/problem/point_add_range_sum)(https://github.com/yosupo06/library-checker-problems/issues/20)
11. [Rectangle Sum](https://judge.yosupo.jp/problem/rectangle_sum)(https://github.com/yosupo06/library-checker-problems/issues/118)
12. [Vertex Add Path Sum](https://judge.yosupo.jp/problem/vertex_add_path_sum)(https://github.com/yosupo06/library-checker-problems/issues/125)
13. [Vertex Add Subtree Sum](https://judge.yosupo.jp/problem/vertex_add_subtree_sum)(https://github.com/yosupo06/library-checker-problems/issues/167)
14. [Static Range Count Distinct](https://judge.yosupo.jp/problem/static_range_count_distinct)(https://github.com/yosupo06/library-checker-problems/issues/770)
15. [Rectangle Add Point Get](https://judge.yosupo.jp/problem/rectangle_add_point_get)(https://github.com/yosupo06/library-checker-problems/issues/994)



Expand Down
69 changes: 31 additions & 38 deletions MATH/Eratosthenes.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ msvc14.2,C++14
#include <algorithm>
#include <bitset>
#include <cstdint>
#include <limits>
#include <numeric>
#include <vector>

Expand Down Expand Up @@ -61,11 +62,11 @@ namespace OY {
template <size_type MAX_RANGE, bool GetPhi = false, bool GetSmallFactor = false, bool GetBigFactor = false>
struct Sieve {
static constexpr size_type max_pi = get_estimated_Pi(MAX_RANGE);
static SieveArray<MAX_RANGE, GetPhi> s_phi;
static SieveArray<MAX_RANGE, GetSmallFactor> s_smallest_factor;
static SieveArray<MAX_RANGE, GetBigFactor> s_biggest_factor;
static size_type s_primes[max_pi], s_prime_cnt;
static std::bitset<MAX_RANGE + 1> s_isprime;
SieveArray<MAX_RANGE, GetPhi> m_phi;
SieveArray<MAX_RANGE, GetSmallFactor> m_smallest_factor;
SieveArray<MAX_RANGE, GetBigFactor> m_biggest_factor;
size_type m_primes[max_pi + 1], m_prime_cnt;
std::bitset<MAX_RANGE + 1> m_isprime;
template <typename Callback>
void _dfs(size_type index, size_type prod, const std::vector<SievePair> &pairs, Callback &&call) const {
if (index == pairs.size())
Expand All @@ -77,46 +78,50 @@ namespace OY {
while (c--) _dfs(index + 1, prod *= p, pairs, call);
}
}
Sieve(size_type range = MAX_RANGE) {
s_isprime.set();
s_isprime.reset(0);
if (range >= 1) s_isprime.reset(1), s_smallest_factor.set(1, 1), s_biggest_factor.set(1, 1), s_phi.set(1, 1);
if (range >= 2) s_smallest_factor.set(2, 2), s_biggest_factor.set(2, 2), s_phi.set(2, 1), s_primes[s_prime_cnt++] = 2;
Sieve(size_type range = MAX_RANGE) { resize(range); }
void resize(size_type range) {
if (!range) return;
m_isprime.set();
m_isprime.reset(0);
m_prime_cnt = 0;
if (range >= 1) m_isprime.reset(1), m_smallest_factor.set(1, 1), m_biggest_factor.set(1, 1), m_phi.set(1, 1);
if (range >= 2) m_smallest_factor.set(2, 2), m_biggest_factor.set(2, 2), m_phi.set(2, 1), m_primes[m_prime_cnt++] = 2;
size_type _sqrt = sqrt(range);
for (size_type i = 3; i <= _sqrt; i += 2)
if (s_isprime[i]) {
s_smallest_factor.set(i, i), s_phi.set(i, i - 1), s_primes[s_prime_cnt++] = i;
if (m_isprime[i]) {
m_smallest_factor.set(i, i), m_phi.set(i, i - 1), m_primes[m_prime_cnt++] = i;
if constexpr (GetBigFactor)
for (size_type j = i; j <= range; j += i) s_biggest_factor.set(j, i);
for (size_type j = i; j <= range; j += i) m_biggest_factor.set(j, i);
for (size_type j = i * i, k = i; j <= range; j += i << 1, k += 2)
if (s_isprime[j]) s_isprime.reset(j), s_smallest_factor.set(j, i), s_phi.set(j, i), s_phi.set(j + 1, k);
if (m_isprime[j]) m_isprime.reset(j), m_smallest_factor.set(j, i), m_phi.set(j, i), m_phi.set(j + 1, k);
} else
s_phi.set(i, s_phi[i + 1] % s_phi[i] ? (s_phi[i] - 1) * s_phi[s_phi[i + 1]] : s_phi[i] * s_phi[s_phi[i + 1]]);
m_phi.set(i, m_phi[i + 1] % m_phi[i] ? (m_phi[i] - 1) * m_phi[m_phi[i + 1]] : m_phi[i] * m_phi[m_phi[i + 1]]);
for (size_type i = _sqrt + _sqrt % 2 + 1; i <= range; i += 2)
if (s_isprime[i]) {
s_smallest_factor.set(i, i), s_phi.set(i, i - 1), s_primes[s_prime_cnt++] = i;
if (m_isprime[i]) {
m_smallest_factor.set(i, i), m_phi.set(i, i - 1), m_primes[m_prime_cnt++] = i;
if constexpr (GetBigFactor)
for (size_type j = i; j <= range; j += i) s_biggest_factor.set(j, i);
for (size_type j = i; j <= range; j += i) m_biggest_factor.set(j, i);
} else
s_phi.set(i, s_phi[i + 1] % s_phi[i] ? (s_phi[i] - 1) * s_phi[s_phi[i + 1]] : s_phi[i] * s_phi[s_phi[i + 1]]);
m_phi.set(i, m_phi[i + 1] % m_phi[i] ? (m_phi[i] - 1) * m_phi[m_phi[i + 1]] : m_phi[i] * m_phi[m_phi[i + 1]]);
m_primes[m_prime_cnt] = std::numeric_limits<size_type>::max() / 2;
}
bool is_prime(size_type i) const { return (i & 1) || i == 2 ? s_isprime[i] : false; }
bool is_prime(size_type i) const { return (i & 1) || i == 2 ? m_isprime[i] : false; }
size_type get_Euler_Phi(size_type i) const {
static_assert(GetPhi);
return (i & 1) ? s_phi[i] : s_phi[i >> std::countr_zero(i)] << std::countr_zero(i) - 1;
return (i & 1) ? m_phi[i] : m_phi[i >> std::countr_zero(i)] << std::countr_zero(i) - 1;
}
size_type query_smallest_factor(size_type i) const {
static_assert(GetSmallFactor);
return (i & 1) ? s_smallest_factor[i] : 2;
return (i & 1) ? m_smallest_factor[i] : 2;
}
size_type query_biggest_factor(size_type i) const {
static_assert(GetBigFactor);
if (i & 1) return s_biggest_factor[i];
if (i & 1) return m_biggest_factor[i];
i >>= std::countr_zero(i);
return i == 1 ? 2 : s_biggest_factor[i];
return i == 1 ? 2 : m_biggest_factor[i];
}
size_type query_kth_prime(size_type k) const { return s_primes[k]; }
size_type count() const { return s_prime_cnt; }
size_type query_kth_prime(size_type k) const { return m_primes[k]; }
size_type count() const { return m_prime_cnt; }
std::vector<SievePair> decomposite(size_type n) const {
static_assert(GetSmallFactor);
std::vector<SievePair> res;
Expand Down Expand Up @@ -150,18 +155,6 @@ namespace OY {
return res;
}
};
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
SieveArray<MAX_RANGE, GetPhi> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_phi;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
SieveArray<MAX_RANGE, GetSmallFactor> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_smallest_factor;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
SieveArray<MAX_RANGE, GetBigFactor> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_biggest_factor;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
size_type Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_primes[Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::max_pi];
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
size_type Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_prime_cnt;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
std::bitset<MAX_RANGE + 1> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_isprime;
}
}

Expand Down
12 changes: 8 additions & 4 deletions MATH/Eratosthenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@

​ 练习题目:

1. [P3383 【模板】线性筛素数](https://www.luogu.com.cn/problem/P3383)
2. [P3449 [POI2006] PAL-Palindromes](https://www.luogu.com.cn/problem/P3449)
3. [P3538 [POI2012] OKR-A Horrible Poem](https://www.luogu.com.cn/problem/P3538)
4. [P3912 素数个数](https://www.luogu.com.cn/problem/P3912)
1. [P2158 [SDOI2008] 仪仗队](https://www.luogu.com.cn/problem/P2158)
2. [P3383 【模板】线性筛素数](https://www.luogu.com.cn/problem/P3383)
3. [P3449 [POI2006] PAL-Palindromes](https://www.luogu.com.cn/problem/P3449)
4. [P3538 [POI2012] OKR-A Horrible Poem](https://www.luogu.com.cn/problem/P3538)
5. [P3912 素数个数](https://www.luogu.com.cn/problem/P3912)
6. [P5221 Product](https://www.luogu.com.cn/problem/P5221)
7. [P6091 【模板】原根](https://www.luogu.com.cn/problem/P6091)
8. [炫酷反演魔术](https://ac.nowcoder.com/acm/problem/244326)

### 二、模板功能

Expand Down
56 changes: 24 additions & 32 deletions MATH/EulerSieve.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ namespace OY {
template <size_type MAX_RANGE, bool GetPhi = false, bool GetSmallFactor = false, bool GetBigFactor = false>
struct Sieve {
static constexpr size_type max_pi = get_estimated_Pi(MAX_RANGE);
static SieveArray<MAX_RANGE, GetPhi> s_phi;
static SieveArray<MAX_RANGE, GetSmallFactor> s_smallest_factor;
static SieveArray<MAX_RANGE, GetBigFactor> s_biggest_factor;
static std::bitset<MAX_RANGE + 1> s_isprime;
static size_type s_primes[max_pi], s_prime_cnt;
SieveArray<MAX_RANGE, GetPhi> m_phi;
SieveArray<MAX_RANGE, GetSmallFactor> m_smallest_factor;
SieveArray<MAX_RANGE, GetBigFactor> m_biggest_factor;
std::bitset<MAX_RANGE + 1> m_isprime;
size_type m_primes[max_pi + 1], m_prime_cnt;
template <typename Callback>
void _dfs(size_type index, size_type prod, const std::vector<SievePair> &pairs, Callback &&call) const {
if (index == pairs.size())
Expand All @@ -77,40 +77,44 @@ namespace OY {
while (c--) _dfs(index + 1, prod *= p, pairs, call);
}
}
Sieve(size_type range = MAX_RANGE) {
s_isprime.set();
s_isprime.reset(0);
if (range >= 1) s_isprime.reset(1), s_smallest_factor.set(1, 1), s_biggest_factor.set(1, 1), s_phi.set(1, 1);
Sieve(size_type range = MAX_RANGE) { resize(range); }
void resize(size_type range) {
if (!range) return;
m_isprime.set();
m_isprime.reset(0);
m_prime_cnt = 0;
if (range >= 1) m_isprime.reset(1), m_smallest_factor.set(1, 1), m_biggest_factor.set(1, 1), m_phi.set(1, 1);
for (int i = 2; i <= range; i++) {
if (s_isprime[i]) s_smallest_factor.set(i, i), s_biggest_factor.set(i, i), s_phi.set(i, i - 1), s_primes[s_prime_cnt++] = i;
for (size_type *it = s_primes, *end = s_primes + s_prime_cnt; it != end; ++it) {
if (m_isprime[i]) m_smallest_factor.set(i, i), m_biggest_factor.set(i, i), m_phi.set(i, i - 1), m_primes[m_prime_cnt++] = i;
for (size_type *it = m_primes, *end = m_primes + m_prime_cnt; it != end; ++it) {
auto p = *it, q = i * p;
if (q > range) break;
s_isprime.reset(q), s_smallest_factor.set(q, p), s_biggest_factor.set(q, s_biggest_factor[i]);
m_isprime.reset(q), m_smallest_factor.set(q, p), m_biggest_factor.set(q, m_biggest_factor[i]);
if (i % p)
s_phi.set(q, s_phi[i] * (p - 1));
m_phi.set(q, m_phi[i] * (p - 1));
else {
s_phi.set(q, s_phi[i] * p);
m_phi.set(q, m_phi[i] * p);
break;
}
}
}
m_primes[m_prime_cnt] = std::numeric_limits<size_type>::max() / 2;
}
bool is_prime(size_type i) const { return (i & 1) || i == 2 ? s_isprime[i] : false; }
bool is_prime(size_type i) const { return (i & 1) || i == 2 ? m_isprime[i] : false; }
size_type get_Euler_Phi(size_type i) const {
static_assert(GetPhi);
return (i & 1) ? s_phi[i] : s_phi[i >> std::countr_zero(i)] << std::countr_zero(i) - 1;
return (i & 1) ? m_phi[i] : m_phi[i >> std::countr_zero(i)] << std::countr_zero(i) - 1;
}
size_type query_smallest_factor(size_type i) const {
static_assert(GetSmallFactor);
return (i & 1) ? s_smallest_factor[i] : 2;
return (i & 1) ? m_smallest_factor[i] : 2;
}
size_type query_biggest_factor(size_type i) const {
static_assert(GetBigFactor);
return s_biggest_factor[i];
return m_biggest_factor[i];
}
size_type query_kth_prime(size_type k) const { return s_primes[k]; }
size_type count() const { return s_prime_cnt; }
size_type query_kth_prime(size_type k) const { return m_primes[k]; }
size_type count() const { return m_prime_cnt; }
std::vector<SievePair> decomposite(size_type n) const {
static_assert(GetSmallFactor);
std::vector<SievePair> res;
Expand Down Expand Up @@ -144,18 +148,6 @@ namespace OY {
return res;
}
};
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
SieveArray<MAX_RANGE, GetPhi> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_phi;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
SieveArray<MAX_RANGE, GetSmallFactor> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_smallest_factor;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
SieveArray<MAX_RANGE, GetBigFactor> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_biggest_factor;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
size_type Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_primes[Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::max_pi];
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
size_type Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_prime_cnt;
template <size_type MAX_RANGE, bool GetPhi, bool GetSmallFactor, bool GetBigFactor>
std::bitset<MAX_RANGE + 1> Sieve<MAX_RANGE, GetPhi, GetSmallFactor, GetBigFactor>::s_isprime;
}
}

Expand Down
Loading

0 comments on commit 88b068b

Please sign in to comment.