ARST打卡第236周[236/521]

Algorithm

lc715_Range模块

思路:
暴力算法就是维护一个pair对,或者直接用kv的map,然后就直接按照key排序了。

这样每次直接根据k-range的左值进行范围查找和计算。

两个 k-range 只有包含,交叠和错开三种状态,所以只要进行处理就行。

这里实现的关键是 lower_bound 对 key 操作是否能实现。
然后时间复杂度是 O(nlog(n)) , n 为最多查询次数。
空间复制度是 O(2n)。

不太熟这个操作,写代码时间超时了,学习一下题解吧。

发现思路和题解完全一样,但是自己的实现速度和坚定度不够,还得多多练习。
并且这里时间复杂度分析把后面的操作算成时间常数,只算了 log(a+r) , 所以时间复杂度也得更细致一点。

给题解加点注释。
发现思路很简单,但是很考验实现速度和精细度。以后还得多练。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class RangeModule {
public:
RangeModule() {}

void addRange(int left, int right) {
// 先找大于 left 的,然后 prev 获取前一个,就能保证 pre_l <= left.
auto it = intervals.upper_bound(left);
if (it != intervals.begin()) {
auto start = prev(it);
// 在前面,pass
if (start->second >= right) {
return;
}
// 交叠处理
if (start->second >= left) {
left = start->first;
intervals.erase(start);
}
}
while (it != intervals.end() && it->first <= right) {
right = max(right, it->second);
it = intervals.erase(it);
}
// it 在最开始找不到时也能顺利到这里。妙。
intervals[left] = right;
}

bool queryRange(int left, int right) {
auto it = intervals.upper_bound(left);
if (it == intervals.begin()) {
return false;
}
it = prev(it);
return right <= it->second;
}

void removeRange(int left, int right) {
auto it = intervals.upper_bound(left);
if (it != intervals.begin()) {
auto start = prev(it);
if (start->second >= right) {
// 从中间切成两段
int ri = start->second;
if (start->first == left) {
intervals.erase(start);
}
else {
start->second = left;
}
if (right != ri) {
intervals[right] = ri;
}
return;
}
else if (start->second > left) {
// 交叠
if (start->first == left) {
intervals.erase(start);
}
else {
start->second = left;
}
}
}
while (it != intervals.end() && it->first < right) {
// right太大,包括删除的范围就多
if (it->second <= right) {
it = intervals.erase(it);
}
else {
intervals[right] = it->second;
intervals.erase(it);
break;
}
}
}

private:
map<int, int> intervals;
};

Review

【TED演讲】你不知道未来的自己想要什么

未来不可知,你不知道未来的自己的想法。
我们可以通过下面三种方式去培育自己让自己成为更好的人:

保持好奇心,保持谦卑,保持勇敢。

Tips

linux学习——软链接、硬链接与复制的区别

Share

vps预览hugo

简单快速预览

因为没有发布,所以一般只能在本地预览,如果是本地操作系统,可以直接查看,但是vps的话,无法直接输出网址查看页面状况。可以通过借助 python 的 http.server 进行简单预览

1
python3 -m http.server 8001

高级预览

如果想要完整预览,还是得用 Nginx 搞个服务,让服务器的 ip 和 port 端口开启对外服务

1
2
# 安装nginx(顺便安装网络排查工具 net-tools)。centos 用 yum install nginx
apt install nginx net-tools
1
2
# vim 配置文件,加上如下配置在 http 的作用域里面
vim /etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# http.server 80 
server {
# ipv4,ipv6 的 80 端口监听
listen 80 default_server;
listen [::]:80 default_server;
server_name us.wolfdan.cn; # 你的域名
root /root/wolfdan.cn/public; # 公开的静态文件路径__不建议放root下,见后文问题排查

include /etc/nginx/default.d/*.conf;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
1
2
3
# 启动 nginx 报错
[root@us-arm public]# nginx
nginx: [emerg] a duplicate default server for [::]:80 in /etc/nginx/nginx.conf:66

需要注释掉默认的 nginx 静态欢迎网页

1
2
- include /etc/nginx/sites-enabled/*;
+ # include /etc/nginx/sites-enabled/*;
1
2
3
4
# 启动 nginx
nginx
# 重启 nginx
nginx -s reload

访问 http://us.wolfdan.cn:80/ 得到的是 403 …
查看日志发现目录权限不够:

1
2
[root@us-arm public]# tail /var/log/nginx/error.log  -n 1
2023/11/09 09:57:57 [error] 866439#866439: *2 "/root/wolfdan.cn/public/index.html" is forbidden (13: Permission denied), client: 141.98.11.60, server: us.wolfdan.cn, request: "GET / HTTP/1.1", host: "141.148.143.17"

观察发现跑 nginx 是一个 www-data 的虚拟用户

1
2
3
4
5
6
7
[root@us-arm wolfdan.cn]# ps aux | grep nginx
root 797588 0.0 0.0 50572 6344 ? Ss 09:41 0:00 nginx: master process nginx
www-data 866439 0.0 0.0 51192 5980 ? S 09:52 0:00 nginx: worker process
www-data 866440 0.0 0.0 51192 5980 ? S 09:52 0:00 nginx: worker process
www-data 866441 0.0 0.0 51192 5980 ? S 09:52 0:00 nginx: worker process
www-data 866442 0.0 0.0 51192 5980 ? S 09:52 0:00 nginx: worker process
root 1107736 0.0 0.0 7700 680 pts/0 S+ 10:28 0:00 grep --color=auto nginx

那就设置 public 目录权限为 www-data .

1
[root@us-arm wolfdan.cn]# chown -R www-data:www-data public

改完还是403,很奇怪…

通过设置 nginx.conf 的 user www-data; 改成 user root; 再 pkill -9 nginx && nginx 重启之后是能够访问页面的。

但是 www-data 为啥不行?

感觉是因为 /root 目录下有特殊的保护机制(原因见下文),导致不行,因为通过尝试复制到其他目录,就成功了…

1
2
[root@us-arm wolfdan.cn]# cp -R public/ /var/www/
[root@us-arm wolfdan.cn]# nginx -s reload

然后想到之前 windows 也无法访问 wsl 的 root 目录,于是明白了是因为 root 目录默认不让其他用户访问.

1
2
3
4
5
6
7
8
9
10
11
12
[root@us-arm /]# ll
total 72
drwxr-xr-x 19 root root 4096 Oct 14 18:17 ./
drwxr-xr-x 19 root root 4096 Oct 14 18:17 ../
lrwxrwxrwx 1 root root 7 Jul 20 05:44 bin -> usr/bin/
drwx------ 2 root root 16384 Jul 20 05:56 lost+found/
# ...
dr-xr-xr-x 246 root root 0 Oct 14 18:17 proc/
# 看这里是无法让其他用户访问的。
drwx------ 11 root root 4096 Nov 9 10:57 root/
# ...
drwxr-xr-x 14 root root 4096 Nov 9 09:19 var/

预览生成的网页

查看发现并没有看到对应的 hello hugo 的文章,是因为默认是 draft ,需要如下方式生成一下。

1
2
3
4
5
6
# *--buildDrafts: 生成被标记为 「草稿」 的文档
# *-w: 监控更改,如果发生更改直接显示到博客上 (保存即可预览效果)
hugo server --buildDrafts -w

# 生成最终文章
hugo

编辑一个脚本直接发到 nginx 目录下

1
2
3
4
5
6
7
8
9
[root@us-arm wolfdan.cn]# vim deploy.sh
[root@us-arm wolfdan.cn]# cat deploy.sh
# 部署到nginx
# rm -rf /var/www/public
cp -R public/ /var/www/
chown -R www-data:www-data /var/www/public
[root@us-arm wolfdan.cn]# sh -x deploy.sh
+ cp -R public/ /var/www/
+ chown -R www-data:www-data /var/www/public

发现还是没有成功看到草稿文章,然后手动去修改了 draft 标签,再次进行上面的生成步骤

1
2
3
4
5
6
7
[root@us-arm wolfdan.cn]# cp content/post/hello-hugo.md content/post/hello-hugo-public.md
[root@us-arm wolfdan.cn]# vim content/post/hello-hugo-public.md
# 修改为 draft = false
[root@us-arm wolfdan.cn]# hugo
[root@us-arm wolfdan.cn]# bash -x deploy.sh
+ cp -R public/ /var/www/
+ chown -R www-data:www-data /var/www/public