惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

PCI Perspectives
PCI Perspectives
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
T
The Blog of Author Tim Ferriss
罗磊的独立博客
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
Recorded Future
Recorded Future
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
Recent Announcements
Recent Announcements
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
Scott Helme
Scott Helme
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
V
Visual Studio Blog
F
Fortinet All Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AI
AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Security Affairs
S
SegmentFault 最新的问题
C
Cisco Blogs
博客园 - 聂微东
MyScale Blog
MyScale Blog
V
Vulnerabilities – Threatpost
量子位
T
The Exploit Database - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Security Latest
Security Latest
P
Proofpoint News Feed
阮一峰的网络日志
阮一峰的网络日志
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
The Last Watchdog
The Last Watchdog

Shiroha白羽的博客

Golang 踩坑 —— interface 为参数的时候传 nil 指针 Codeforces Round 925 (Div. 3) Codeforces Round 924 (Div. 2) Codeforces Round 923 (Div. 3) Codeforces Round 922 (Div. 2) Codeforces Round 921 (Div. 2) Educational Codeforces Round 161 (Rated for Div. 2) Codeforces Round 920 (Div. 3) Codeforces Round 919 (Div. 2) Hello 2024 Good Bye 2023 Codeforces Round 918 (Div. 4) 个人备份的常用 macOS 清理命令 Codeforces Round 917 (Div. 2) Pinely Round 3 (Div. 1 + Div. 2) Educational Codeforces Round 160 (Rated for Div. 2) Codeforces Round 915 (Div. 2) Codeforces Round 914 (Div. 2) Codeforces Round 913 (Div. 3) Educational Codeforces Round 159 (Rated for Div. 2) Codeforces Round 912 (Div. 2) Codeforces Round 911 (Div. 2) CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!) Educational Codeforces Round 158 (Rated for Div. 2) Codeforces Round 910 (Div. 2) Codeforces Round 909 (Div. 3) Codeforces Round 908 (Div. 2) Educational Codeforces Round 157 (Rated for Div. 2) C++自定义的字面量 Codeforces Round 907 (Div. 2) Codeforces Round 916 (Div. 3) 关于 LRU map 的一些灵感 2023 杭州站 ICPC 现场赛 反复横跳的 Clang-Tidy(cert-dcl21-cpp) Codeforces Round 906 (Div. 2) 一段奇怪的 CPP 代码 Codeforces Round 905 (Div. 3) Codeforces Round 904 (Div. 2) Codeforces Round 903 (Div. 3) Educational Codeforces Round 156 (Rated for Div. 2) Codeforces Round 902 (Div. 2, based on COMPFEST 15 - Final Round) Codeforces Round 901 (Div. 2) Codeforces Round 900 (Div. 3) Codeforces Round 899 (Div. 2) Educational Codeforces Round#155 (Div. 2) Codeforces Round 898 (Div. 4) CodeTON Round 6 (Div. 2) Codeforces Round 897 (Div. 2) Codeforces Round 896 (Div. 2) Codeforces Round 887 (Div. 2) Codeforces Round 895 (Div. 3) 左值-右值-将亡值 blog.mauve.icu Pinely Round 2 (Div. 1 + Div. 2) Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2) Codeforces Round 894 (Div. 3) Codeforces Round 888 (Div. 3) Educational Codeforces Round#153 (Div. 2) Codeforces Round 893 (Div. 2) OTPAUTH,两步验证中的通用协议 Codeforces Round 892 (Div. 2) Codeforces Round 891 (Div. 3) Codeforces Round 890 (Div. 2) blog.mauve.icu Java Script 的 null 和 undefined 随想 记一次 SQL LEFT JOIN 没有得到预期结果的错误 Codeforces Round#789(Div. 2) GCC/G++ 预编译头性能优化 使用 Junit5 和 Mockito 实现 SpringBoot 的单元测试最优美的解决方案 centOS 防火墙 docker-compse 的问题 C++ 语言实现动态变化的线程池 Codeforces Round#744 (Div. 3) 计算机图形学 Windows 通过网络访问 WSL2 原生 JavaScript 实现图片裁剪 面试复习(计算机图形学) 面试复习(算法) Codeforces Round#706(Div. 2)-Let's Go Hiking 面试复习(Java) 面试复习(Git) 面试复习(Linux) 面试复习(数据库) 面试复习(计算机网络) 面试复习(操作系统) 面试复习(C++) Codeforces Round#699 (Div. 2) 清理 WSL2 的磁盘占用 Codeforces Round#697 (Div. 3) Windows 下的 NTFS 驱动器索引 BUG 计算机网络复习 记一次 Navicat 连接 MySQL 一直报认证错误(Access denied) 计算机网络实验复习 WSL1 使用 Docker 一直无法启动 我的ACM脚印 2020牛客暑期多校训练营(第三场)D-Points Construction Problem——构造 2020牛客暑期多校训练营(第三场)E-Two Matchings——复杂思维与简单dp 2020牛客暑期多校训练营(第二场)I-Interval——最大流转对偶图求最短路 Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理 Codeforces Round 606 E. Two Fairs——图论 Codeforces Round 612 (Div. 2) C. Garland——DP
Educational Codeforces Round#152 (Div. 2)
Shiroha · 2023-08-06 · via Shiroha白羽的博客

A. Morning Sandwich

大致题意

有 $a$ 个面包片,$b$ 个奶酪片,$c$ 个火腿片,要保证奶酪片和火腿片必须被两块面包片直接夹,问最多可以造多大的汉堡

思路

很简单,就不讲了

AC code

1
2
3
4
5
6
7
8
9
10
void solve() {
int _;
cin >> _;
for (int tss = 0; tss < _; ++tss) {
int a, b, c;
cin >> a >> b >> c;
int m = min(a - 1, b + c);
cout << m * 2 + 1 << endl;
}
}

B. Monsters

大致题意

有 $n$ 个怪物,每个怪物有一定生命值 $a[i]$,每次攻击一定是对着生命值最高的怪物,并减少其生命值 $k$,若有多个则选择最左边的,问怪物的死亡顺序

思路

当有任何怪物的生命值大于 $k$ 的时候,那就意味着不会有怪物死亡,所以可以先对所有怪物进行 mod k 操作

此时,就会有怪物出现死亡,因为会恰好降低到 $0$,需要先输出为 $0$ 的怪物,从左往右输出即可

后面,再根据剩余生命值从大到小,从左往右输出即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void solve() {
int _;
cin >> _;
for (int tss = 0; tss < _; ++tss) {
int n, k;
cin >> n >> k;
map<int, vector<int>> res;
for (int i = 0; i < n; ++i) {
int tmp;
cin >> tmp;
tmp %= k;
res[tmp].push_back(i);
}
auto zero = res[0];
for (auto i : zero) cout << i + 1 << ' ';
for (auto iter = res.rbegin(); iter != res.rend(); ++iter) {
if (iter->first == 0) continue;
for (auto i : iter->second) cout << i + 1 << ' ';
}
cout << endl;
}
}

C. Binary String Copying

这题老坑人了QAQ

大致题意

有一个初始字符串 $s$,仅有 01 组成。

有 $k$ 次操作,每次操作都是在这个初始字符串上进行的。每次操作选择一个区间 $[l, r]$,并使得这个区间内的值进行排序,即 $0101010 \rightarrow 0000111$

问,得到的这 $k$ 个字符串,有多少种不同的

思路

有点蒙,但还是得找找思路

考虑到字符串种类,第一反应是做字符串 hash,这非常简单,因为字符串仅有 01,为了方便,如果当前位为 1 则取这一位的权制,否则不取,这样就有点类似 $mod$ 进制数了

接下来是如何计算 $k$ 个字符串的 hash 值,根据题目给出的数据量,看起来必须在 O(sqrt(n)) 时间之内完成。我们可以发现,每次操作后实际上有三个区间

  • $[1, l)$ 和原来的 hash 值相同
  • $[l, r]$ 不知道!
  • $(r, n]$ 和原来的 hash 值相同

即然某段区间存在和之前 hash 值相同的情况,那么可以通过对 hash 值前缀和的方式,使得能够快速求出任意区间的 hash 值,那么就只剩下中间的区间了

有意思的是,排序后的值恰好是一个前面为 0 后面为 1 的字符串,所以计算单独计算这段区间内的 hash 结果非常简单,只需要有一个每一位的 hash 值的前缀和,并且知道 1 从哪一位开始即可,因为最后一个一定也是 1(当然需要排除一下压根没有 1 的情况)

而需要计算某个区间内的 1 的数量,好像又可以做一次前缀和

最终,只需要三个前缀和就可以简单解决问题了

但是试了两个 hash 值都不通过,一气之下直接同时计算两个 hash 值,然后就过了

AC code

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
void solve() {
int _;
cin >> _;
vector<int> pw1(2e5 + 10);
vector<int> pw2(2e5 + 10);
int tmp1 = 1;
int tmp2 = 1;
int mod = 998244353;
for (int i = 1; i < pw1.size(); ++i) {
pw1[i] = (pw1[i - 1] + tmp1) % mod;
tmp1 *= 131;
tmp1 %= mod;

pw2[i] = (pw2[i - 1] + tmp2) % mod;
tmp2 *= 1331;
tmp2 %= mod;
}
for (int ts = 0; ts < _; ++ts) {
int n, k;
cin >> n >> k;
vector<int> a(n + 1), b1(n + 1), b2(n + 1);
string str(n, '0');
cin >> str;

tmp1 = 1;
tmp2 = 1;
for (int i = 0; i < n; ++i) {
a[i + 1] = a[i] + str[i] - '0';
b1[i + 1] = (b1[i] + (str[i] == '1' ? tmp1 : 0)) % mod;
tmp1 *= 131;
tmp1 %= mod;

a[i + 1] = a[i] + str[i] - '0';
b2[i + 1] = (b2[i] + (str[i] == '1' ? tmp2 : 0)) % mod;
tmp2 *= 1331;
tmp2 %= mod;
}

set<pair<int, int>> res;
for (int i = 0; i < k; ++i) {
int l, r;
cin >> l >> r;

int ls, rs;
{
int left = b1[l - 1] % mod;
int right = (b1[n] - b1[r] + mod) % mod;
int one = a[r] - a[l - 1];
int zero = r - l + 1 - one;
int from = l + zero, to = r;
int mid = (pw1[to] - pw1[from - 1] + mod) % mod;
ls = (left + right + mid) % mod;
}
{
int left = b2[l - 1] % mod;
int right = (b2[n] - b2[r] + mod) % mod;
int one = a[r] - a[l - 1];
int zero = r - l + 1 - one;
int from = l + zero, to = r;
int mid = (pw2[to] - pw2[from - 1] + mod) % mod;
rs = (left + right + mid) % mod;
}
res.insert({ls, rs});
}

cout << res.size() << endl;
}
}

D. Array Painting

大致题意

有一段数组 $a$,每个值必定是 $0, 1, 2$ 其中一个,开始的时候所有值都是蓝色的,你可以进行如下操作

  • 选择一个蓝色的值,把它变成红色,同时支付一块钱
  • 选择一个红色的值,若其大于 $0$,则将其减少 $1$,并将一个相邻它的值改为红色

问,你最少需要支付多少钱才能把所有值变成红色

大致思路

容易明白的是,无论如何先随便找个 $2$ 染色的一定不亏,然后这个 $2$ 就会向两侧染色,直到遇到 $0$。那么这样处理完成后,再找下一个没有被染色的 $2$,直到 $2$ 被全部耗尽

然后是 $0, 1$ 的问题了,很明显的是,在一段连续没有被染色的区间下,可以分类讨论

  • 如果只有 $1$,那么恭喜,染色一个端点,就可以染色全部
  • 如果只有 $0$,那么就得一个个染色
  • 如果同时有 $1$ 和 $0$
    • 因为每一段连续的 $1$ 可以附带染色一个相邻的 $0$,实际上操作几个 $1$ 等于也染色了几个 $0$,所以最终结果一般还是得跟 $0$ 数量相同
    • 但是从第一条种可以得到,因为一段 $1$ 就得花费一次染色,不能只看 $0$ 的数量,例如 $101$ 这种情况下,虽然只有一个 $0$,但是 $1$ 有两端,则至少需要染色 $2$ 次(实际上就是因为第二段 $1$ 不会染色任何其他 $0$)

所以结论为,每一段没有染色的区间,需要 $max(cnt_0, cnt_part1)$ 的花费

AC code

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
void solve() {
int n;
cin >> n;
vector<int> data(n);
vector<bool> vis(n, false);
int res = 0;
for (int i = 0; i < n; ++i) cin >> data[i];

// 先处理 2 的情况
for (int i = 0; i < n; ++i) {
if (vis[i] || data[i] != 2) continue;
res++;
vis[i] = true;
for (int j = i - 1; j >= 0; --j) {
if (!vis[j]) {
vis[j] = true;
if (data[j] == 0) break;
} else break;
}
for (; i < n; ++i) {
vis[i] = true;
if (data[i] == 0) break;
}
}

// 再处理 1 的情况
int last = -1;
int zero = 0;
int oneP = 0;
for (int i = 0; i < n; ++i) {
if (vis[i]) {
res += max(oneP, zero);
zero = 0;
oneP = 0;
last = -1;
} else if (data[i] == 0) {
zero++;
last = 0;
} else if (last != 1) {
last = 1;
oneP++;
}
}
res += max(oneP, zero);

cout << res << endl;
}