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

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

Shiroha白羽的博客

Codeforces Round 1089 (Div. 2) Codeforces Round 1079 (Div. 2) 2025 总结 The Burrows-Wheeler Transform 块排序压缩算法 Summer Pockets 动画完结 香港银行开卡记-1 【转载】Rust 中常见的有关生命周期的误解 Codeforces Round 972 (Div. 2) 《黑神话:悟空》游玩评测 Golang 踩坑 —— interface 为参数的时候传 nil 指针 用 magic 变量解决 UAF 问题 Codeforces Round 942 (Div. 2) Codeforces Round 941 (Div. 2) Codeforces Round 940 (Div. 2) and CodeCraft-23 日本旅游杂记-东京篇 Codeforces Round 939 (Div. 2) Codeforces Round 928 (Div. 4) Codeforces Round 927 (Div. 3) Codeforces Round 926 (Div. 2) 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) 左值-右值-将亡值 Educational Codeforces Round#154 (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) Educational Codeforces Round#152 (Div. 2) Codeforces Round#889 (Div. 2) Java Script 的 null 和 undefined 随想 记一次 SQL LEFT JOIN 没有得到预期结果的错误 Codeforces Round#789(Div. 2) GCC/G++ 预编译头性能优化 使用 Junit5 和 Mockito 实现 SpringBoot 的单元测试最优美的解决方案 centOS 防火墙 docker-compse 的问题 Gitbook 安装出错 macOS 更新后导致 sdk 丢失问题 Java 生成验证码 Captcha C++ 模版可变参数列表传递给 C 的 va_list 可变参数列表 GitHub 下载的 zip 代码如何与原仓库再次建立连接 2021年浙江工商大学新生赛题解 Dockerfile 中下载 JDK8 Mac 使用带 python 的 vim Mac 截图唤起速度慢 C++ 语言实现动态变化的线程池 Strassen算法代码 Codeforces Round#744 (Div. 3)
Pinely Round 2 (Div. 1 + Div. 2)
2023-09-01 · via Shiroha白羽的博客

A. Channel

大致题意

你是一个频道的频道主,然后发了一条消息,同时你能知道订阅者上下线的消息(不知道具体是谁),上线的人必定看你的消息,问有没有可能所有人都看过你的消息了

思路

简单题,统计最大同时在线,和最多多少在线,就可以了

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, a, q;
cin >> n >> a >> q;
string str;
str.reserve(q);
cin >> str;
int ma = a, tot = a, cur = a;
for (auto &item: str) {
if (item == '+') {
cur++;
tot++;
ma = max(ma, cur);
} else cur--;
}
cout << (ma >= n ? "YES" : tot >= n ? "MAYBE" : "NO") << endl;
}
}

B. Split Sort

大致题意

有一个 $n$ 的排列,每次选择一个数组中的一个值,将小于它的值放左边,大于等于的放右边,顺序不变,问最多操作几次后数组有序

思路

第一反应就是归并排序,太像了,只需要算出归并排序需要几次就行了

但是这个值可以说是确定的,即几乎等于 $n$,这是归并的性质决定的。而实际上已经基本排序好的数组,压根不需要那么多次

再仔细思考操作带来的意义,实际上本身顺序并没有发生太大变动,假如移动的是 $x$,那么对于除开 $x$ 以外的所有值而言,在 $[1, x)$ 内都没有发生相对位置变化,同理对于 $[x, n]$ 也是,但是跨 $x$ 的相对位置都变成正确的了。即当对任意的 $x$ 进行操作后,实际上就解决掉了 $x$ 关联的全部的逆序对问题,以及跨越 $x$ 的逆序对。

综上可以得到,若不选择 $x$ 的情况下,那么若 $x - 1$ 在 $x$ 的右侧情况下,那么必然永远不能消除此逆序对。所以只需要找出这样的逆序对,然后进行操作即可。至于剩下的逆序对,在完成上述操作后,自然已经满足要求了,这里不再详细证明

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n;
cin >> n;
set<int> flag;
int ans = 0;
for (int i = 0; i < n; ++i) {
int tmp;
cin >> tmp;
if (flag.count(tmp + 1)) ans++;
flag.insert(tmp);
}
cout << ans << endl;
}
}

C. MEX Repetition

大致题意

给一个长度为 $n$ 的数组,其值在 $[0, n]$ 内,且没有重复

每次操作,需要依次对每一个值进行 $MEX$ 计算,并代替当前的值,问进行 $x$ 次操作后,数组变成什么样

思路

在数组最后补上没有的那个值,然后你就会发现只是在旋转数组罢了

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, k;
cin >> n >> k;
vector<int> data(n + 1);
set<int> flag;
for (int i = 0; i <= n; ++i) flag.insert(i);
for (int i = 0; i < n; ++i) cin >> data[i];
for (int i = 0; i < n; ++i) flag.erase(data[i]);
data[n] = *flag.begin();
k %= (n + 1);
for (int i = 0; i < n; ++i) cout << data[(i + n + 1 - k) % (n + 1)] << " \n"[i == n - 1];
}
}

D. Two-Colored Dominoes

大致题意

有一个 $n \times m$ 的矩阵,矩阵上放着很多小木板,一块木板一定恰好占用两个相邻的格子,木板之间不重叠。

现在要给木板上色,黑色和白色,一块木板占用的两个格子,必须不同颜色。矩阵内任意一行一列都必须黑白色相同数量,给出一种上色法

思路

要相同,必然占用的格子数量是偶数

结论很简单,竖着的木板在同行的数量(或者横着的木板在同列的数量)一定是偶数

可以简单画一下错开的情况,就会发现无解了

知道这个结论之后随便画一下就好了

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
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, m;
cin >> n >> m;
vector<string> ans(n);
for (auto &row: ans) {
row.reserve(m);
cin >> row;
}

bool flag = true;
for (int i = 0; i < n; ++i) {
int last = -1;
for (int j = 0; j < m; ++j) {
// for U
if (ans[i][j] != 'U') continue;
if (last == -1) last = j;
else {
ans[i][j] = 'W';
ans[i + 1][j] = 'B';
ans[i][last] = 'B';
ans[i + 1][last] = 'W';
last = -1;
}
}
if (last != -1) {
flag = false;
break;
}
}

for (int j = 0; j < m; ++j) {
int last = -1;
for (int i = 0; i < n; ++i) {
// for L
if (ans[i][j] != 'L') continue;
if (last == -1) last = i;
else {
ans[i][j] = 'W';
ans[i][j + 1] = 'B';
ans[last][j] = 'B';
ans[last][j + 1] = 'W';

last = -1;
}
}
if (last != -1) {
flag = false;
break;
}
}

if (!flag) {
cout << -1 << endl;
continue;
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) cout << ans[i][j];
cout << endl;
}
}
}

E. Speedrun

大致题意

有 $n$ 个任务,每个任务完成需要的时间可以忽略不计,但是每个任务都有指定的完成时间点。时间是循环的,即类似自然时间,23 点之后又是 0 点。任务之间也有依赖关系

问最短需要多少时间完成这些任务

思路

一开始写了一个拓扑排序找,然后三分了所有可能的开始时间点($[0, k]$),理论上时间应该来得及,但是不知道为什么 TLE 了

后面开始仔细思考其他解决方案

实际上每个节点的时间可以看成是 $h_i + x * k$,即需要求出最大和最小值之差。然后对于第一批没有依赖的任务,他们可以是第一天完成的,也可以是第二天完成的,但是不可能是第三天完成的。故可以考枚举无依赖的任务是否是第二天完成的,然后计算此时最大的完成时间。由于无依赖任务本身也是有时间的,根据时间排序后遍历的话,若当前是第二天完成的,那么前面的也都是第二天完成的了,就不需要每次单独计算了,可以让下一次的状态是从上一次变化过来的,这样计算成本非常小

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
69
70
71
72
73
74
75
76
#define int long long

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, m, k;
cin >> n >> m >> k;

struct node {
int v, n;

bool operator<(const node &rhs) const {
return rhs.v < v;
}
};

vector<int> cost(n);
vector<int> head(n, -1);
vector<node> edge(m);
vector<int> deg(n, 0);
for (auto &item: cost) cin >> item;
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
edge[i] = {v - 1, head[u - 1]};
head[u - 1] = i;
deg[v - 1]++;
}

queue<int> q;
vector<int> begin;
for (int i = 0; i < n; ++i)
if (deg[i] == 0) {
q.push(i);
begin.push_back(i);
}

int mx = 0, ans = LONG_LONG_MAX;
while (!q.empty()) {
int cur = q.front();
q.pop();

mx = max(mx, cost[cur]);
for (int i = head[cur]; i != -1; i = edge[i].n) {
--deg[edge[i].v];
cost[edge[i].v] += ((max(0LL, cost[cur] - cost[edge[i].v]) + k - 1) / k) * k;
if (deg[edge[i].v] == 0) q.push(edge[i].v);
}
}
sort(begin.begin(), begin.end(), [&](const int &lhs, const int &rhs) {
return cost[lhs] < cost[rhs];
});

ans = min(ans, mx - cost[begin.front()]);

function<void(int)> add = [&](int x) {
mx = max(mx, cost[x]);
for (int i = head[x]; i != -1; i = edge[i].n) {
if (cost[edge[i].v] - cost[x] >= 0) continue;
cost[edge[i].v] += ((max(0LL, cost[x] - cost[edge[i].v]) + k - 1) / k) * k;
add(edge[i].v);
}
};

for (auto &item : begin) {
ans = min(ans, mx - cost[item]);
cost[item] += k;
add(item);
}

ans = min(ans, mx - cost[begin.front()]);

cout << ans << endl;
}
}