Educational Codeforces Round 171 (Rated for Div. 2)

比赛链接

Problems AC
A. Perpendicular Segments
B. Black Cells
C. Action Figures
D. Sums of Segments
E. Best Subsequence
F. Bermart Ice Cream

C

最有意思的一个题。由于所有的东西都要买,转化为最多能用多少优惠。

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
void solve() {
int n = read();

string s;
cin >> s;

s = '#' + s;
int ans = 0;

std::queue<int> q;
for (int i = n; i >= 1; i--) {
if (s[i] == '0') {
ans += i;
if (!q.empty()) {
q.pop();
}
} else {
q.ep(i);
}
}

int m = q.size() / 2;
while (m--) q.pop();

while (!q.empty()) {
ans += q.front();
q.pop();
}

cout << ans << '\n';
}

D

分块前缀和套前缀和,算算算算就过了。

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
void solve() {
int n = read();

vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
a[i] = read();
// siz[i] = n - i + 1;
}

vector<int> suma(n + 1);
for (int i = 1; i <= n; i++) {
suma[i] = suma[i - 1] + a[i];
}

vector<int> sum2a(n + 1);
for (int i = 1; i <= n; i++) {
sum2a[i] = sum2a[i - 1] + suma[i];
}

vector<int> block_sum(n + 1);
block_sum[1] = sum2a[n];
for (int i = 2; i <= n; i++) {
block_sum[i] = block_sum[i - 1] - a[i - 1];
block_sum[i] -= (n - i + 1) * (a[i - 1]);
}

// for (int i = 1; i <= n; i++) {
// cout << block_sum[i] << '\n';
// }

for (int i = 1; i <= n; i++) {
block_sum[i] += block_sum[i - 1];
}

auto get = [&](int x) {
int res = 0;

int p = 0;
for (int l = 1, r = n; l <= r; ) {
int mid = l + r >> 1;
if ((n + n - mid + 1) * mid / 2 < x) {
p = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
res += block_sum[p];

x -= (n + n - p + 1) * p / 2;
res += sum2a[x + p] - sum2a[p] - suma[p] * x;
return res;
};

for (int q = read(); q--; ) {
int l = read(), r = read();
cout << get(r) - get(l - 1) << '\n';
// cout << get(r) << '\n';
}
}

E

最大权闭合子图。

从 s 向 1…n 连 1

1…n 向 1…60 中对应的 bit 位连 inf。

1…60 向 t 连 1。

经典结论之:最大权闭合子图的权值等于所有正权点(与 s 直接相连的点集)权值之和减去最小割

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
void solve() {
int n = read();

MaxFlow<int> g(n + 1 + 60 + 2);

int node = n + 60;
int s = ++node;
int t = ++node;

for (int i = 1; i <= 60; i++) {
g.addEdge(n + i, t, 1);
}

for (int i = 1; i <= n; i++) {
int x = read();
g.addEdge(s, i, 1);
for (int j = 0; j < 60; j++) {
if (x >> j & 1) {
g.addEdge(i, n + j + 1, inf);
}
}
}

cout << n - g.flow(s, t) << '\n';
}
Author

TosakaUCW

Posted on

2024-11-05

Updated on

2024-11-11

Licensed under

Comments