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

推荐订阅源

Google DeepMind News
Google DeepMind News
TaoSecurity Blog
TaoSecurity Blog
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tenable Blog
C
Cybersecurity and Infrastructure Security Agency CISA
GbyAI
GbyAI
Microsoft Security Blog
Microsoft Security Blog
N
Netflix TechBlog - Medium
AWS News Blog
AWS News Blog
Security Latest
Security Latest
L
LINUX DO - 热门话题
Blog — PlanetScale
Blog — PlanetScale
T
Threatpost
Stack Overflow Blog
Stack Overflow Blog
Vercel News
Vercel News
S
Securelist
I
Intezer
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Heimdal Security Blog
T
The Exploit Database - CXSecurity.com
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
H
Hackread – Cybersecurity News, Data Breaches, AI and More
U
Unit 42
The Register - Security
The Register - Security
NISL@THU
NISL@THU
S
Schneier on Security
M
MIT News - Artificial intelligence
The Last Watchdog
The Last Watchdog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
Y
Y Combinator Blog
Know Your Adversary
Know Your Adversary
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
美团技术团队
W
WeLiveSecurity
P
Privacy International News Feed
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
小众软件
小众软件
博客园 - 【当耐特】
P
Proofpoint News Feed
P
Privacy & Cybersecurity Law Blog
T
Tor Project blog

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) Educational Codeforces Round#152 (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 一直无法启动 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
Codeforces Round 1102 (Div. 2)
Shiroha · 2026-06-13 · via Shiroha白羽的博客

A. Euclid, Sequence and Two Numbers

大致题意

定义一种特殊的序列,满足 $\forall 1 \leq i \leq n - 2, a_{i+2} = a_i \space mod \space a_{i+1}$

现在给出一个数组,确认其是否满足

思路

注意到:我们只需要检查一下数组是否满足就行

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;
cin >> n;
vector<int> v(n);
for (int i = 0; i < n; ++i) cin >> v[i];
sort(v.begin(), v.end(), greater<int>());

bool flag = true;
for (int i = 0; i < n - 2; ++i) flag &= v[i] % v[i + 1] == v[i + 2];
if (flag) cout << v[0] << ' ' << v[1] << endl;
else cout << -1 << endl;
}
}

B. Palindrome, Twelve and Two Terms

大致题意

给出一个 $n$,要求找到两个数字 $a, b$,满足: $a$ 为回文串,$b$ 为 $12$ 的 $x$ 倍

思路

注意到:$1, 2, 3 \dots 9, 11$ 就是回文串,而一个数去掉一个 $12$ 的倍数的数字后,必定是 $1, 2, 3 \dots 11$

我们可以注意到其中只有 $10$ 不满足回文,其他数字均满足回文,所以如果 $n = 12x + y, y \in \left { 1, 2, 3, \dots 9, 11 \right } $

我们直接把 $b$ 设置为最大可能值,即 $n % 12$ 的结果为 $a$ 即可

接下来讨论 $y = 10$ 的情况,显然,如果我们可以从 $b$ 让一个 $12$ 出来,我们就可以得到 $22$ 这个回文串。所以仅当 $n = 10$ 的时候无解

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define int long long

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n;
cin >> n;
if (n == 10) {
cout << -1 << endl;
} else if (n % 12 != 10) {
const int x = n / 12;
cout << n - x * 12 << ' ' << x * 12 << endl;
} else {
const int x = n / 12 - 1;
cout << n - x * 12 << ' ' << x * 12 << endl;
}
}
}

D. XOR, Expression and Two Binary Numbers

大致题意

有 $2^k + 1$ 个数组 $a$,其中第 $1, 2^k + 1$ 两个值已知,其他值未知

剩余值可以通过如下公式算出:如果 $a_i, a_j$ 已知,则 $a_{\frac{i + j}{2}} = a_i XOR a_j$

接下来定义 $x_i$ 为 $a_i$ 这个数值在二进制上,$1$ 的数量,同样的 $y_i$ 为 $0$ 的数量(注意,固定二进制长度为 $n$,即有可能存在前导 0)

问 $\sum_{i=1}^n x_i \times y_i$ 是多少

思路

$XOR$ 运算的性质考察:$A XOR A = 0$,所以我们定义最开始的两个值分别为 $A, B$,那么他们异或结果为 $C = A \space XOR \space B$

那么 $A \space XOR \space B = C$, $A \space XOR \space C = B$, $B \space XOR \space C = A$

那么当 $k = 1$ 时,数组为:$A, C, B$
当 $k = 2$ 时,数组为 $A, B, C, A, B$
当 $k = 3$ 时,数组为 $A, C, B, A, C, B, A, C, B$

以此类推可以发现规律

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
#define int long long

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, k;
cin >> n >> k;
string a, b, c;
a.reserve(n);
b.reserve(n);
cin >> a >> b;
c.resize(n);
for (int i = 0; i < n; ++i) c[i] = a[i] == b[i] ? '0' : '1';
int ca[2] = {0, 0}, cb[2] = {0, 0}, cc[2] = {0, 0};
for (int i = 0; i < n; ++i) {
++ca[a[i] - '0'];
++cb[b[i] - '0'];
++cc[c[i] - '0'];
}
int va = 0, vb = 0, vc = 0;
va = ca[0] * ca[1];
vb = cb[0] * cb[1];
vc = cc[0] * cc[1];

if (k & 1) cout << ((2LL << (k - 1)) + 1) / 3 * (va + vb + vc) << endl;
else cout << va + vb + (va + vb + vc) * ((2LL << (k - 1)) - 1) / 3 << endl;

}
}

F. Vessels, Heights and Two Versions (Hard Version)

大致题意

有一个 $n$ 个柱子组成的一个环形的接水容器,现在要求计算:要求某两个相邻的柱子之间没有水,整个容器最多可以承接多少水

思路

首先,观察数据量,显然这道题至少需要在 $O(n log n)$ 时间内,完成 $n$ 个数据计算,那么可以得到,只有两种可能:

  1. 纯离线计算出所有结果
  2. 前一个数据可以通过一定代码推导至下一个结果,且耗时不超过 $O(log n)$

显然看起来 2 方案更可靠一些,我们需要往这个方向考虑。

首先环状的柱子理解较为困难,实际上我们可以考虑将其拆开:沿着不允许有水的两根柱子之间的位置剪开后,可以得到一个水平的柱子图

由于恰好这两个边缘的柱子虽然本来相邻,但是因为他们中间不允许有水,那么其实问题就变成了:

  • 计算当前的水平柱子群能最多维持多少水不往两侧流出(两侧其实就是那个不允许的装水的两个柱子之间的部分)
  • 将第一个柱子挪到最后,重新计算

单独计算一次(独立一次计算)非常容易,就像普通的接雨水那样做就行,那么显然,我们需要计算清楚:

  • 第一个柱子移开后,会导致多少水丢失
  • 第一个柱子放到最后后,会带来多少水

接下来是关于这个问题的一些重要的分析思路

柱子贡献

我们需要计算每一根柱子的贡献,我们有两种方式,以下面的例子为例

方案一:

柱高: 5 3 1 5
水高: 5 5 5
贡献: 9 5 1 0

方案二:

柱高: 5 3 1 5
水高: 5 5 5
贡献: 15 0 0 0

显然方案二下,计算贡献更简单,且适合单调数列来完成计算,但是每次移动柱子则需要更多的计算成本:即还原回方案一

而方案一的计算代价则较大。我选择了方案二进行计算

单调数组

所有的水池会呈现一种抛物曲线形状,例如:$123454321$ 的两端矮,中间高的情况。所以我们在计算的过程中,必然需要从原始数组中提取双向的单调数组

显然,我们取最高的那一个(如果有多个则任取其一)作为固定的点:
左边采用递增数组,右边使用递减数组,就可以很好的维护当前的水位——对于单调数组的每两项相邻值
使用这两个值的下标之差 $\times$ 两个值中的较小者,就是这块维护起来的水池

偏移法

首先,显然,计算每次需要解散、新增的水池,需要做两个事情:计算高度、计算距离。

  • 距离非常容易,即相邻单调数组的相邻两个值的下标差。
  • 但是高度却比较难。
    • 虽然看起来,在单调数组内,我们直接取相邻数据中,较小的那个就行。
    • 但是实际操作中会发现一种情况,即被认为最高的那个柱子发生移动
    • 此时,所有的单调数组就都无效,且需要全部重建:
    • 因为左边肯定已经空了,而右边又突然增加了一个最大的值导致递减数列变成唯一项了(我们的递减数列要求最后一项必须在数组中)

这显然不符合简单设计原则,我的做法是:考虑到循环问题,我们直接将数组拷贝一份,将原来的 $n$ 长度的数组变为 $2n$ 长度,这样循环的过程,就变成了在这个 $2n$ 上截取一度 $n$ 长度的内容,每次移动及将窗口右移一格

同样的,我们可以直接强制设定初始的 $n$ 为 $i \to j$,其中 $j$ 为最大值的下标,这样我们就不存在将这个最大值进行挪动了:它开始在最后面,结束在最前面,恰好完成一轮答案计算

那么我们可知:所有数据最开始都在左边的递增单调数组,右边的为空数组

还原贡献

柱高: 5 3 1 5
水高: 5 5 5
贡献: 15 0 0 0

回到刚刚这个问题,我们还需要解决一个事情是:如何在将 $5$ 移动到最后的过程中,正确还原 $3$、$1$ 的贡献:

这个办法就在最初构建左侧的单调数组的过程中:因为当 $5$ 加入的时候 $3$ 被移除。我们只需要记录这个移除的事件,当 $5$ 被移除的时候,还原这些被移除的值就行。

而因为我们选择了方案二,贡献计算非常简单:当 $3$ 被移回的时候,左边的数组变成 $3(index: 1), 5(index: 3)$,那么可以直接用最小高度 $\times$ 下标差来实时计算贡献

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
77
#define int long long

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n;
cin >> n;
vector<int> data(n);
for (int i = 0; i < n; ++i) cin >> data[i];
int max_index = 0;
for (int i = 1; i < n; ++i) max_index = data[i] >= data[max_index] ? i : max_index;
max_index += max_index == n - 1 ? 0 : n;
vector<int> l, r, ans(n);
vector<list<int>> pops(n);
l.reserve(n);
r.reserve(n);

auto c_len = [&](int x, int y) {
x %= n;
y %= n;
if (y > x) return y - x;
else return y - x + n;
};

// push left
int cur = 0;
for (int i = max_index - 1, j = 1; j < n; --i, ++j) {
while (!l.empty() && data[i % n] > data[l.back() % n]) {
const int p = l.back();
pops[i % n].push_back(p);
l.pop_back();
const int hei = data[p % n];
const int len = c_len(p, l.empty() ? max_index : l.back());
cur -= hei * len;
}

const int hei = data[i % n];
const int len = c_len(i, l.empty() ? max_index : l.back());
cur += hei * len;
l.push_back(i);
}
ans[(max_index + 1) % n] = cur;
for (int i = max_index + 1 - n, j = 1; j < n; ++i, ++j) {
// remove l
l.pop_back();
int hei = data[i % n];
int len = c_len(i, l.empty() ? max_index : l.back());
cur -= hei * len;

// add pops
for (auto iter = pops[i % n].rbegin(); iter != pops[i % n].rend(); ++iter) {
hei = data[*iter % n];
len = c_len(*iter, l.empty() ? max_index : l.back());
cur += hei * len;
l.push_back(*iter);
}

// add r
while (!r.empty() && data[r.back() % n] < data[i % n]) {
const int p = r.back();
r.pop_back();
hei = data[p % n];
len = c_len(r.empty() ? max_index : r.back(), p);
cur -= hei * len;
}

hei = data[i % n];
len = c_len(r.empty() ? max_index : r.back(), i);
cur += hei * len;
r.push_back(i % n + n);
ans[(i + 1) % n] = cur;
}

for (int i = 0; i < n; ++i) cout << ans[i] << " \n"[i == n - 1];
}
}