Skip to content

Commit 0ecfcf8

Browse files
committed
添加了若干内容,修复了若干内容
1 parent 0c8839a commit 0ecfcf8

5 files changed

Lines changed: 591 additions & 12 deletions

File tree

README.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
**当前最新普通版发布版本为 `v1.2.0`****最新打印版发布版本为 `v1.2.0` (总词数约10.0w(含代码))**
1+
**当前最新普通版发布版本为 `v1.2.2`****最新打印版发布版本为 `v1.2.0` (总词数约10.0w(含代码))**
22

33
成品为 `template.pdf` (移步 [releases](https://github.com/lr580/algorithm_template/releases) 查看/下载)
44

@@ -293,15 +293,31 @@ lr580's 算法模板
293293

294294
## 更新日志
295295

296+
- 23/10-27 - 24/06/05 (`v1.2.2`)
297+
298+
- 添加了动态开点线段树模板
299+
300+
- 微加了位运算语法应用
301+
- 添加了暴力 LCA
302+
- 微修了 Dijkstra 最短路应用例子表述错误、朴素法代码等
303+
- 添加了调试输出版本的语法
304+
- 添加了枚举组合 Gosper's Hack 模板
305+
- 修正了整数三分模板
306+
- 增加了树上 k 级祖先倍增法
307+
- 增加了背包方案数模板
308+
- 修正了 Miller Rabin 素性测试复杂度
309+
- 微加了差分约束内容
310+
- 微修了 STL vector 语法表述错误
311+
296312
- 23/10/22 - 23/10/26 (`v1.2.1`)
297313

298314
- 重制了匹配问题等目录排版
299-
315+
300316
- 微加了 STL 内容
301317
- 添加了树状数组上倍增、线段树上二分、pb_ds 哈希表
302318
- 修正了整数三分模板
303319
- 添加了立体计算几何公式
304-
320+
305321
- 23/10/19 - 23/10/21 (`v1.2.0`)
306322

307323
- 添加了快速矩阵前 n 项和模板

code/gospers_hack.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
// Function to generate the next subset
5+
unsigned int nextSubset(unsigned int subset) {
6+
unsigned int u = subset & -subset;
7+
unsigned int v = subset + u;
8+
return v | (((v ^ subset) / u) >> 2);
9+
}
10+
11+
// Function to generate all k-subsets of a set of size n
12+
void gospersHack(int k, int n) {
13+
unsigned int subset = (1 << k) - 1;
14+
unsigned int limit = (1 << n);
15+
16+
while (subset < limit) {
17+
// Process the subset here
18+
// For example, printing it out
19+
for (int i = 0; i < n; ++i) {
20+
if (subset & (1 << i)) {
21+
std::cout << i + 1 << " ";
22+
}
23+
}
24+
std::cout << std::endl;
25+
26+
subset = nextSubset(subset);
27+
}
28+
}
29+
30+
int main() {
31+
int k = 3; // Size of subsets
32+
int n = 5; // Size of the set
33+
34+
std::cout << "All " << k << "-subsets of a " << n << "-element set:\n";
35+
gospersHack(k, n);
36+
37+
return 0;
38+
}

code/lca_tarjan.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include <algorithm>
2+
#include <cstring>
3+
#include <iostream>
4+
using namespace std;
5+
6+
class Edge {
7+
public:
8+
int toVertex, fromVertex;
9+
int next;
10+
int LCA;
11+
Edge() : toVertex(-1), fromVertex(-1), next(-1), LCA(-1){};
12+
Edge(int u, int v, int n) : fromVertex(u), toVertex(v), next(n), LCA(-1){};
13+
};
14+
15+
const int MAX = 100;
16+
int head[MAX], queryHead[MAX];
17+
Edge edge[MAX], queryEdge[MAX];
18+
int parent[MAX], visited[MAX];
19+
int vertexCount, queryCount;
20+
21+
void init() {
22+
for (int i = 0; i <= vertexCount; i++) {
23+
parent[i] = i;
24+
}
25+
}
26+
27+
int find(int x) {
28+
if (parent[x] == x) {
29+
return x;
30+
} else {
31+
return find(parent[x]);
32+
}
33+
}
34+
35+
void tarjan(int u) {
36+
parent[u] = u;
37+
visited[u] = 1;
38+
39+
for (int i = head[u]; i != -1; i = edge[i].next) {
40+
Edge& e = edge[i];
41+
if (!visited[e.toVertex]) {
42+
tarjan(e.toVertex);
43+
parent[e.toVertex] = u;
44+
}
45+
}
46+
47+
for (int i = queryHead[u]; i != -1; i = queryEdge[i].next) {
48+
Edge& e = queryEdge[i];
49+
if (visited[e.toVertex]) {
50+
queryEdge[i ^ 1].LCA = e.LCA = find(e.toVertex);
51+
}
52+
}
53+
}
54+
55+
int main() {
56+
memset(head, 0xff, sizeof(head));
57+
memset(queryHead, 0xff, sizeof(queryHead));
58+
59+
cin >> vertexCount >> queryCount;
60+
int count = 0;
61+
for (int i = 0; i < vertexCount - 1; i++) {
62+
int start = 0, end = 0;
63+
cin >> start >> end;
64+
65+
edge[count] = Edge(start, end, head[start]);
66+
head[start] = count;
67+
count++;
68+
69+
edge[count] = Edge(end, start, head[end]);
70+
head[end] = count;
71+
count++;
72+
}
73+
74+
count = 0;
75+
for (int i = 0; i < queryCount; i++) {
76+
int start = 0, end = 0;
77+
cin >> start >> end;
78+
79+
queryEdge[count] = Edge(start, end, queryHead[start]);
80+
queryHead[start] = count;
81+
count++;
82+
83+
queryEdge[count] = Edge(end, start, queryHead[end]);
84+
queryHead[end] = count;
85+
count++;
86+
}
87+
88+
init();
89+
tarjan(1);
90+
91+
for (int i = 0; i < queryCount; i++) {
92+
Edge& e = queryEdge[i * 2];
93+
cout << "(" << e.fromVertex << "," << e.toVertex << ") " << e.LCA << endl;
94+
}
95+
96+
return 0;
97+
}

code/segment_tree_lazy.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <bits/stdc++.h> // https://leetcode.cn/problems/range-module
2+
using namespace std;
3+
using ll = long long;
4+
class RangeModule
5+
{
6+
constexpr static ll inf = 1e9;
7+
constexpr static ll maxn = 60 * 1e4; // log(inf)*q
8+
struct node
9+
{
10+
ll ls, rs, sum, laz;
11+
} t[maxn] = {};
12+
int cnt = 1;
13+
#define cll const ll &
14+
#define mkcf ll cf = (lf + rf) >> 1
15+
void pushdown(int r, cll lf, cll rf)
16+
{
17+
if (!t[r].ls)
18+
t[r].ls = ++cnt;
19+
if (!t[r].rs)
20+
t[r].rs = ++cnt;
21+
if (!t[r].laz)
22+
return;
23+
if (t[r].laz == 1)
24+
{
25+
mkcf;
26+
t[t[r].ls].sum = (cf - lf + 1); // len-len/2
27+
t[t[r].rs].sum = rf - cf; // len/2
28+
}
29+
else
30+
{
31+
t[t[r].ls].sum = t[t[r].rs].sum = 0;
32+
}
33+
t[t[r].ls].laz = t[t[r].rs].laz = t[r].laz;
34+
t[r].laz = 0;
35+
}
36+
void pushup(int r)
37+
{
38+
t[r].sum = t[t[r].ls].sum + t[t[r].rs].sum;
39+
}
40+
void update(int r, ll lf, ll rf, cll lc, cll rc, cll v)
41+
{
42+
if (lc <= lf && rf <= rc)
43+
{
44+
t[r].sum += (v == 1) * (rf - lf + 1);
45+
t[r].laz = v;
46+
return;
47+
}
48+
pushdown(r, lf, rf);
49+
mkcf;
50+
if (lc <= cf)
51+
update(t[r].ls, lf, cf, lc, rc, v);
52+
if (rc >= cf + 1)
53+
update(t[r].rs, cf + 1, rf, lc, rc, v);
54+
pushup(r);
55+
}
56+
ll query(int r, ll lf, ll rf, cll lc, cll rc)
57+
{
58+
if (lc <= lf && rf <= rc)
59+
return t[r].sum;
60+
pushdown(r, lf, rf);
61+
ll res = 0;
62+
mkcf;
63+
if (lc <= cf)
64+
res += query(t[r].ls, lf, cf, lc, rc);
65+
if (rc >= cf + 1)
66+
res += query(t[r].rs, cf + 1, rf, lc, rc);
67+
return res;
68+
}
69+
70+
public:
71+
RangeModule() {}
72+
73+
void addRange(int left, int right)
74+
{
75+
update(1, 1, inf, left, right - 1, 1);
76+
}
77+
78+
bool queryRange(int left, int right)
79+
{
80+
return query(1, 1, inf, left, right - 1) == right - left;
81+
}
82+
83+
void removeRange(int left, int right)
84+
{
85+
update(1, 1, inf, left, right - 1, -1);
86+
}
87+
};
88+
89+
signed main()
90+
{
91+
ios::sync_with_stdio(false), cin.tie(0);
92+
93+
return 0;
94+
}
95+
96+
/**
97+
* Your RangeModule object will be instantiated and called as such:
98+
* RangeModule* obj = new RangeModule();
99+
* obj->addRange(left,right);
100+
* bool param_2 = obj->queryRange(left,right);
101+
* obj->removeRange(left,right);
102+
*/

0 commit comments

Comments
 (0)