Imy、Endorfin. —— 雨雫とプレアデス

以前没有发现 sky_delta 这么厉害。

22 qoj9588 可重集合

线段树分治,然后直接 bitset 维护吧。是 O(V/w×nlogn)O(V/w \times n\log n) 的。


The 3rd Universal Cup. Stage 37: Wuhan

23 C. One Must Imagine Sisyphus Happy

24 E.

25 H.

26 J.


[蓝桥杯 2025 国 A] 公路

https://www.luogu.com.cn/problem/P12849

转化成对每种颜色断边然后统计连通块大小是容易的,然后我直接线段树分治了是何意味啊,这又不是图。

DFS 一次就好,维护每种颜色“当前”的连通块大小,走过一条边就断边。

27. 2026 钉耙编程暑期 01 数字子序列

https://acm.hdu.edu.cn/contest/problem?cid=1229&pid=1008

给定一个 10510^5 的数字串,从中选出若干个连续的段组成数字,这些段构成上升子序列,问最长长度。8s。

直接暴力转移,因为长度是 O(n)O(\sqrt{n}) 的。

当前轮每个数的排名可以由上一轮的结果递推出,其实就是基数排序。

以下,我总感觉我写了一坨。

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
#include <bits/stdc++.h>
#define uint unsigned int
using namespace std;
constexpr int N = 1e5 + 5;

uint n;
int f[2][N];
int g[2][N]; // = max(f[ <= i][ <= j])
int rk[N]; // 开头为 x 的东西的排名

struct Fenwick {
int C[N];
void clear() { fill(C + 1, C + n + 1, -1e9); }
void add(int x, int k) { for (; x <= n; x += x & -x) C[x] = max(C[x], k); }
int qmax(int x) const { int r = -1e9; for (; x; x -= x & -x) r = max(r, C[x]); return r; }
} F;


void solve() {
string a; cin >> a; n = a.length();

vector<int> lst;
for (int i = n - 1; i >= 0; --i) lst.emplace_back(i);

memset(f, 0, sizeof f);
memset(g, 0, sizeof g);

const int B = ceil(sqrt(n * 2)) + 5;

for (int j = 0; j < B; ++j) {
const int len = j;
vector<int> pos[10];
for (int i : lst)
pos[a[i] - '0'].emplace_back(i);
lst.clear();
int tot = 0;
for (int k = 0; k < 10; ++k)
for (const int x : pos[k]) {
if (x) lst.emplace_back(x - 1);
rk[x] = ++tot;
}

F.clear();
for (int i = j; i < n; ++i) {
f[j & 1][i] = 1;

if (!(j && a[i - j] == '0')) {
if (i >= j + 1) f[j & 1][i] = max(f[j & 1][i], g[j - 1 & 1][i - j - 1] + 1); // i - j - 1 >= j - 1
}

f[j & 1][i] = max(f[j & 1][i], F.qmax(rk[i - j] - 1) + 1);

if (i - j >= j) F.add(rk[i - j - j], f[j & 1][i - j]);
}

for (int i = 0; i < n; ++i) {
g[j & 1][i] = f[j & 1][i];
if (i) g[j & 1][i] = max(g[j & 1][i], g[j & 1][i - 1]);
if (j) g[j & 1][i] = max(g[j & 1][i], g[j - 1 & 1][i]);
}
}

cout << g[B - 1 & 1][n - 1] << '\n';
}

int main(void) {
ios::sync_with_stdio(false);
uint T; cin >> T;
while (T--) solve();
return 0;
}

Nothing built can last forever.
本站由 iznomia 使用 Stellar 1.30.4 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。