Skip to content

Commit 8c7bda4

Browse files
committed
feat: cleaned AI wordings
1 parent 9718a37 commit 8c7bda4

21 files changed

Lines changed: 1650 additions & 1620 deletions

File tree

scripts/clean_text.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import os
2+
3+
def clean_text(lines):
4+
# `lines` is an iterator over the lines of a file (without "\n").
5+
out = ""
6+
for line in lines:
7+
if line.startswith("---") \
8+
or (line.startswith("#") and any([wd in line for wd in ["引言", "总结", "结语"]])): continue
9+
if line.startswith("#") and any([(n + "、") in line for n in "一二三四五六七八九十"]):
10+
mark, text = line.split(" ", 1)
11+
text = text.split("、", 1)[1]
12+
line_ = f"{mark} {text}"
13+
else:
14+
line_ = line
15+
out += line_ + "\n"
16+
return out
17+
18+
if __name__ == "__main__":
19+
src_dir = "./src/content/blog/"
20+
for date in os.listdir(src_dir):
21+
file = os.path.join(src_dir, date, "index.md")
22+
with open(file, "r", encoding="utf-8") as f:
23+
lines = iter(f.read().splitlines())
24+
three_dashes_count = 0
25+
metadata = ""
26+
for line in lines:
27+
if line.startswith("---"): three_dashes_count += 1
28+
metadata += line + "\n"
29+
if three_dashes_count == 2: break
30+
cleaned = clean_text(lines)
31+
with open(file, "w", encoding="utf-8") as f:
32+
f.write(metadata + cleaned)

scripts/writer.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import glob
99
import yaml
10+
import clean_text
1011

1112
path_to = f'src/content/blog/{datetime.datetime.now().strftime("%Y-%m-%d")}'
1213

@@ -129,7 +130,7 @@ def beautify_string(text):
129130
summary_result = beautify_string(summary(article))
130131
print(f" Decided Summary: {summary_result}; time spent {time.time() - start:.1f} s")
131132

132-
lines = iter(article.split("\n"))
133+
lines = iter(article.splitlines())
133134
markdown_file = ""
134135
author = random.choice(["杨其臻", "杨子凡", "叶家炜", "黄京"])
135136
print(f" Rolled author: {author}")
@@ -152,10 +153,7 @@ def beautify_string(text):
152153
markdown_file += metadata
153154
break
154155

155-
for line in lines:
156-
if line.startswith("---") \
157-
or (line.startswith("#") and any([wd in line for wd in ["引言", "总结", "结语"]])): continue
158-
markdown_file += line + "\n"
156+
markdown_file += clean_text.clean_text(lines)
159157

160158
with open(f"{path_to}/index.md", "w", encoding="utf-8") as f:
161159
f.write(markdown_file)
Lines changed: 82 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,82 @@
1-
---
2-
title: "前缀和引入"
3-
author: "杨子凡"
4-
date: "Nov 28, 2024"
5-
description: "前缀和系列第一篇"
6-
latex: true
7-
pdf: true
8-
---
9-
10-
## 引入
11-
12-
> 荀子曰:不积跬步,无以至千里;不积小流,无以成江海。
13-
14-
这句话揭示了世间万物整体和部分之间的关系——庞大的整体由若干个体组成;单个个体虽小,但经过一点一滴的累积,也能聚成一个庞大的整体。学习工作贵在不断积累,不断充实、丰富、完善自己,所有的努力都会有回报。
15-
16-
在算法竞赛中,利用整体和部分的性质可以达成很多目的,例如利用前缀和可以在常数时间复杂度中查询区间和,利用差分在常数时间复杂度对序列进行区间操作,或者利用离散化去除无用数据区间,通过放缩保留有用的数据。这些操作使得我们不必每次都要重复处理个体的数据,而是直接对整体进行处理,从而降低时间复杂度,提升运算效率。
17-
18-
本篇将介绍前缀和的基础算法与实现,帮助读者掌握这一重要的工具。
19-
20-
## 前缀和的定义
21-
22-
前缀和是一种简单而高效的算法思想。对于一个数组 `a`,它的前缀和数组 `prefix` 定义如下:
23-
24-
$$
25-
\mathrm{prefix}_n = \sum _{i=1} ^{n} a_i
26-
$$
27-
28-
通过前缀和,我们可以在 $\mathcal{O}(1)$ 的时间复杂度内快速计算任意区间 $[l, r]$ 的和,公式如下:
29-
30-
$$
31-
\mathrm{sum}_{l,r} = \mathrm{prefix}_r - \mathrm{prefix}_{l-1}
32-
$$
33-
34-
其中,当 $l = 1$ 时,$\mathrm{sum}_{l,r} = \mathrm{prefix}_r$。
35-
36-
## 算法实现
37-
38-
接下来我们讲上面的思想运用到一道具体的题目中来看一下前缀和的具体使用方法。
39-
40-
~~由于笔者是洛谷忠实粉丝,这次包括之后的所有练习题可能大概率来自洛谷,建议各位今早注册账号跟着笔者一起练习。~~
41-
42-
我们选用洛谷的 [B3612](https://www.luogu.com.cn/problem/B3612),由于其实现思路与定义中所讲内容完全雷同,这里直接上代码:
43-
44-
45-
```cpp
46-
#include <bits/stdc++.h>
47-
48-
using namespace std;
49-
50-
int n, m, a[100050], s[100050];
51-
52-
inline int read() {
53-
int f = 1, x = 0; char ch = getchar();
54-
while (ch < '0' or ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
55-
while (ch >= '0' and ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
56-
return f*x;
57-
}
58-
59-
int main() {
60-
n = read();
61-
for (int i = 1; i <= n; i ++)
62-
s[i] = s[i - 1] + (a[i] = read()); //构造前缀和数组
63-
m = read();
64-
for (int i = 1; i <= m; i ++) {
65-
int l = read(), r = read();
66-
cout << s[r] - s[l - 1] << endl; //根据上文公式得出
67-
}
68-
return 0;
69-
}
70-
```
71-
72-
目前,如果你能完全理解以上代码,你已经掌握了前缀和的最基础运用。下一章将会介绍前缀和在差分中的运用。
73-
74-
编者按:如果你喜欢比较更偏 C++ 的实现方法,你还可以这样实现前缀和:
75-
76-
```cpp
77-
vector<int> values(n); // 假设其中已有数据
78-
vector<int> prefixSums(1);
79-
for (auto i : values) prefixSums.push_back(prefixSums.back() + i);
80-
```
81-
82-
其中 `vector<int> prefixSums(1)` 定义了一个长度为 1 且值为 0 的向量,随后的 `for` 循环中则每次把 `values` 中的一项与这个前缀和向量的最后一项相加,然后添加到后者中。
1+
---
2+
title: "前缀和引入"
3+
author: "杨子凡"
4+
date: "Nov 28, 2024"
5+
description: "前缀和系列第一篇"
6+
latex: true
7+
pdf: true
8+
---
9+
10+
## 引入
11+
12+
> 荀子曰:不积跬步,无以至千里;不积小流,无以成江海。
13+
14+
这句话揭示了世间万物整体和部分之间的关系——庞大的整体由若干个体组成;单个个体虽小,但经过一点一滴的累积,也能聚成一个庞大的整体。学习工作贵在不断积累,不断充实、丰富、完善自己,所有的努力都会有回报。
15+
16+
在算法竞赛中,利用整体和部分的性质可以达成很多目的,例如利用前缀和可以在常数时间复杂度中查询区间和,利用差分在常数时间复杂度对序列进行区间操作,或者利用离散化去除无用数据区间,通过放缩保留有用的数据。这些操作使得我们不必每次都要重复处理个体的数据,而是直接对整体进行处理,从而降低时间复杂度,提升运算效率。
17+
18+
本篇将介绍前缀和的基础算法与实现,帮助读者掌握这一重要的工具。
19+
20+
## 前缀和的定义
21+
22+
前缀和是一种简单而高效的算法思想。对于一个数组 `a`,它的前缀和数组 `prefix` 定义如下:
23+
24+
$$
25+
\mathrm{prefix}_n = \sum _{i=1} ^{n} a_i
26+
$$
27+
28+
通过前缀和,我们可以在 $\mathcal{O}(1)$ 的时间复杂度内快速计算任意区间 $[l, r]$ 的和,公式如下:
29+
30+
$$
31+
\mathrm{sum}_{l,r} = \mathrm{prefix}_r - \mathrm{prefix}_{l-1}
32+
$$
33+
34+
其中,当 $l = 1$ 时,$\mathrm{sum}_{l,r} = \mathrm{prefix}_r$。
35+
36+
## 算法实现
37+
38+
接下来我们讲上面的思想运用到一道具体的题目中来看一下前缀和的具体使用方法。
39+
40+
~~由于笔者是洛谷忠实粉丝,这次包括之后的所有练习题可能大概率来自洛谷,建议各位今早注册账号跟着笔者一起练习。~~
41+
42+
我们选用洛谷的 [B3612](https://www.luogu.com.cn/problem/B3612),由于其实现思路与定义中所讲内容完全雷同,这里直接上代码:
43+
44+
45+
```cpp
46+
#include <bits/stdc++.h>
47+
48+
using namespace std;
49+
50+
int n, m, a[100050], s[100050];
51+
52+
inline int read() {
53+
int f = 1, x = 0; char ch = getchar();
54+
while (ch < '0' or ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
55+
while (ch >= '0' and ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
56+
return f*x;
57+
}
58+
59+
int main() {
60+
n = read();
61+
for (int i = 1; i <= n; i ++)
62+
s[i] = s[i - 1] + (a[i] = read()); //构造前缀和数组
63+
m = read();
64+
for (int i = 1; i <= m; i ++) {
65+
int l = read(), r = read();
66+
cout << s[r] - s[l - 1] << endl; //根据上文公式得出
67+
}
68+
return 0;
69+
}
70+
```
71+
72+
目前,如果你能完全理解以上代码,你已经掌握了前缀和的最基础运用。下一章将会介绍前缀和在差分中的运用。
73+
74+
编者按:如果你喜欢比较更偏 C++ 的实现方法,你还可以这样实现前缀和:
75+
76+
```cpp
77+
vector<int> values(n); // 假设其中已有数据
78+
vector<int> prefixSums(1);
79+
for (auto i : values) prefixSums.push_back(prefixSums.back() + i);
80+
```
81+
82+
其中 `vector<int> prefixSums(1)` 定义了一个长度为 1 且值为 0 的向量,随后的 `for` 循环中则每次把 `values` 中的一项与这个前缀和向量的最后一项相加,然后添加到后者中。
Lines changed: 75 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,75 @@
1-
---
2-
title: "前缀和与差分"
3-
author: "杨子凡"
4-
date: "Dec 9, 2024"
5-
description: "前缀和系列第二篇"
6-
latex: true
7-
pdf: true
8-
---
9-
10-
## 引入
11-
12-
> 画龙点睛,事半功倍。
13-
14-
差分算法的思想就是通过巧妙的修改差值而不是直接修改原数组,从而优化时间复杂度。利用差分,我们可以在常数时间复杂度内对一个区间进行修改,而不需要遍历整个区间。结合前缀和进行求和,我们可以在 $\mathcal{O}(1)$ 的时间内完成区间修改操作。算法中的这些优化技巧在实际问题中非常高效,尤其是在面对大数据量时。
15-
16-
本篇将介绍如何运用差分优化区间修改操作,并利用前缀和求解区间和。
17-
18-
## 差分的思想
19-
20-
差分是前缀和的逆过程,用于高效处理区间修改。给定一个数组 $a$,我们可以通过构造一个差分数组 $d$ 来记录数组相邻元素的差值。
21-
22-
假设 $d_i$ 记录的是数组 $a_i$ 与 $a_{i-1}$ 之间的差异,即:
23-
24-
$$d_i=a_i-a_{i-1}$$
25-
26-
利用差分数组,我们可以在常数时间内对区间进行修改。
27-
28-
## 区间修改
29-
30-
给定一个区间 $[l, r]$,我们需要将区间内的每个元素都加上一个常数 $x$。直接修改原数组会导致 $\mathcal{O}(r-l+1)$ 的时间复杂度,而使用差分数组,我们可以通过如下操作:
31-
32-
1. 对差分数组 $d_l$ 加上 $x$(表示区间开始处增加 $x$)。
33-
2. 对差分数组 $d_{r+1}$ 减去 $x$(表示区间结束后增加的部分被取消)。
34-
35-
这样,区间修改的时间复杂度就变为 $\mathcal{O}(1)$。
36-
37-
## 算法实现
38-
39-
还是来看一道例题,是洛谷的[P2367](https://www.luogu.com.cn/problem/P2367)
40-
41-
```cpp
42-
#include <bits/stdc++.h>
43-
#define F(_b, _e) for (int i = _b; i <= _e; i ++)
44-
using namespace std;
45-
46-
const int MAXN = 5e6 + 5;
47-
int a[MAXN];
48-
int main() {
49-
int n, p; n = read(); p = read();
50-
int tmp = 0;
51-
F (1, n) {
52-
int k = read();
53-
a[i] = k - tmp;
54-
tmp = k;
55-
}
56-
F (1, p) {
57-
int l, r, d;
58-
l = read(); r = read(); d = read();
59-
a[l] += d;
60-
a[r + 1] -= d;
61-
}
62-
tmp = 0;
63-
int ans = 5e5;
64-
F (1, n) {
65-
tmp += a[i];
66-
ans = min(ans, tmp);
67-
}
68-
write(ans);
69-
return 0;
70-
}
71-
```
72-
73-
目前你已经掌握了前缀和的基本方法以及通过差分加前缀和的方法优化区间修改的时间复杂度。
74-
75-
但是,这样对于区间修改的时间复杂度的优化会导致查询的时间复杂度急剧上升,没差一个都要从第一项求前缀和到该项,那么,有没有什么方法可以使得修改和查询时间复杂度都降低呢?这将会是我们前缀和这一期第三篇的内容,下一篇将会有很大难度,各位做好心理准备。
1+
---
2+
title: "前缀和与差分"
3+
author: "杨子凡"
4+
date: "Dec 9, 2024"
5+
description: "前缀和系列第二篇"
6+
latex: true
7+
pdf: true
8+
---
9+
10+
## 引入
11+
12+
> 画龙点睛,事半功倍。
13+
14+
差分算法的思想就是通过巧妙的修改差值而不是直接修改原数组,从而优化时间复杂度。利用差分,我们可以在常数时间复杂度内对一个区间进行修改,而不需要遍历整个区间。结合前缀和进行求和,我们可以在 $\mathcal{O}(1)$ 的时间内完成区间修改操作。算法中的这些优化技巧在实际问题中非常高效,尤其是在面对大数据量时。
15+
16+
本篇将介绍如何运用差分优化区间修改操作,并利用前缀和求解区间和。
17+
18+
## 差分的思想
19+
20+
差分是前缀和的逆过程,用于高效处理区间修改。给定一个数组 $a$,我们可以通过构造一个差分数组 $d$ 来记录数组相邻元素的差值。
21+
22+
假设 $d_i$ 记录的是数组 $a_i$ 与 $a_{i-1}$ 之间的差异,即:
23+
24+
$$d_i=a_i-a_{i-1}$$
25+
26+
利用差分数组,我们可以在常数时间内对区间进行修改。
27+
28+
## 区间修改
29+
30+
给定一个区间 $[l, r]$,我们需要将区间内的每个元素都加上一个常数 $x$。直接修改原数组会导致 $\mathcal{O}(r-l+1)$ 的时间复杂度,而使用差分数组,我们可以通过如下操作:
31+
32+
1. 对差分数组 $d_l$ 加上 $x$(表示区间开始处增加 $x$)。
33+
2. 对差分数组 $d_{r+1}$ 减去 $x$(表示区间结束后增加的部分被取消)。
34+
35+
这样,区间修改的时间复杂度就变为 $\mathcal{O}(1)$。
36+
37+
## 算法实现
38+
39+
还是来看一道例题,是洛谷的[P2367](https://www.luogu.com.cn/problem/P2367)
40+
41+
```cpp
42+
#include <bits/stdc++.h>
43+
#define F(_b, _e) for (int i = _b; i <= _e; i ++)
44+
using namespace std;
45+
46+
const int MAXN = 5e6 + 5;
47+
int a[MAXN];
48+
int main() {
49+
int n, p; n = read(); p = read();
50+
int tmp = 0;
51+
F (1, n) {
52+
int k = read();
53+
a[i] = k - tmp;
54+
tmp = k;
55+
}
56+
F (1, p) {
57+
int l, r, d;
58+
l = read(); r = read(); d = read();
59+
a[l] += d;
60+
a[r + 1] -= d;
61+
}
62+
tmp = 0;
63+
int ans = 5e5;
64+
F (1, n) {
65+
tmp += a[i];
66+
ans = min(ans, tmp);
67+
}
68+
write(ans);
69+
return 0;
70+
}
71+
```
72+
73+
目前你已经掌握了前缀和的基本方法以及通过差分加前缀和的方法优化区间修改的时间复杂度。
74+
75+
但是,这样对于区间修改的时间复杂度的优化会导致查询的时间复杂度急剧上升,没差一个都要从第一项求前缀和到该项,那么,有没有什么方法可以使得修改和查询时间复杂度都降低呢?这将会是我们前缀和这一期第三篇的内容,下一篇将会有很大难度,各位做好心理准备。

0 commit comments

Comments
 (0)