Skip to content

Commit 92535ab

Browse files
committed
Stuff
1 parent fd5e17f commit 92535ab

File tree

3 files changed

+112
-18
lines changed

3 files changed

+112
-18
lines changed

Baltic/Baltic 15-edi.cpp

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
/*
22
Baltic 2015 Editor
3-
- Firstly, the last operation is always active
4-
- Secondly, if operation y can't undo x but operation z can
5-
undo x where x < y < z, then z can undo y
6-
- This means for each operation, we only care about the
7-
most recent operation whose level is strictly less than
8-
the current operation
9-
- View the sequence as a tree now
10-
- Connect each operation to the other operation
11-
mentioned above
12-
- This means we can use binary lifting to find which
13-
operation to undo by also storing suffix minimums
14-
- Thirdly, if we view the sequence of numbers we get as a trie,
15-
each operation moves us either up or down a single node
16-
- This means only the current letter can be undone
17-
- So if we undo operation x with operation y, the answer
18-
for operation y is the answer for operation x - 1
19-
- Operation x - 1 must be active after operation y,
20-
so connect y with x - 1
3+
- Firstly, notice how if x can't undo y and z can't undo x, then z can't undo y.
4+
- Let each operation be a node.
5+
- If undo operation x undoes operation y, draw an edge between x and y - 1 and let par[x] = y - 1.
6+
- Notice how the answer for x is the answer for par[x].
7+
- Consider an undo operation z.
8+
- If z can't undo x, then z can't undo any operation in the range (par[x], x].
9+
- This is because par[x] + 1 is the most recent active operation x could undo and the states of the nodes (par[x] + 1, x] remain unchanged.
10+
- This still holds when we undo some operations.
11+
- Therefore, the operation we undo must lie on some path from the most recent operation upwards.
12+
- We can use suffix minimums and binary lifting to find this operation.
2113
- Complexity: O(N log N)
2214
*/
2315

Innopolis/Innopolis 19-stones.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
- It's optimal to fill a stove to its maximum capacity if we put any stones in it
3+
- So we place V stones in (S - 1) / V stoves and (S - 1) % V + 1 stones in 1 stove
4+
- Do DP to calculate the result quickly
5+
- Complexity: O(N^2)
6+
*/
7+
8+
#include <bits/stdc++.h>
9+
#define FOR(i, x, y) for (int i = x; i < y; i++)
10+
typedef long long ll;
11+
using namespace std;
12+
13+
ll a[1001], dp[1001][1001][2][3];
14+
15+
int main() {
16+
ios_base::sync_with_stdio(0);
17+
cin.tie(0);
18+
ll n, s, v;
19+
cin >> n >> s >> v;
20+
FOR(i, 1, n) cin >> a[i];
21+
22+
if (s <= n / 2 * v) return cout << 0, 0;
23+
24+
ll to_fill = (s - 1) / v, rem = (s - 1) % v + 1;
25+
memset(dp, 0x3f, sizeof(dp));
26+
dp[0][0][0][0] = dp[0][1][0][1] = dp[0][0][1][2] = 0;
27+
28+
FOR(i, 1, n) FOR(j, 0, to_fill + 1) {
29+
dp[i][j][0][0] = *min_element(dp[i - 1][j][0], dp[i - 1][j][0] + 3);
30+
dp[i][j][1][0] = *min_element(dp[i - 1][j][1], dp[i - 1][j][1] + 3);
31+
32+
if (j) {
33+
dp[i][j][0][1] = min(dp[i - 1][j - 1][0][0], dp[i - 1][j - 1][0][1] + a[i] * v * v);
34+
dp[i][j][1][1] = min(dp[i - 1][j - 1][1][0], min(dp[i - 1][j - 1][1][1] + a[i] * v * v, dp[i - 1][j - 1][1][2] + a[i] * rem * v));
35+
}
36+
37+
dp[i][j][1][2] = min(dp[i - 1][j][0][0], dp[i - 1][j][0][1] + a[i] * rem * v);
38+
}
39+
40+
cout << *min_element(dp[n - 1][to_fill][1], dp[n - 1][to_fill][1] + 3) << '\n';
41+
return 0;
42+
}

infoarena/infoarena biconex.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Biconnected Components
3+
*/
4+
5+
#include <bits/stdc++.h>
6+
#define FOR(i, x, y) for (int i = x; i < y; i++)
7+
typedef long long ll;
8+
using namespace std;
9+
10+
vector<int> graph[100001], stck;
11+
vector<vector<int>> bccs;
12+
int low[100001], tin[100001], timer = 1;
13+
14+
void dfs(int node = 1, int parent = 0) {
15+
low[node] = tin[node] = timer++;
16+
stck.push_back(node);
17+
18+
for (int i : graph[node]) if (i != parent) {
19+
if (tin[i]) low[node] = min(low[node], tin[i]);
20+
else {
21+
dfs(i, node);
22+
low[node] = min(low[node], low[i]);
23+
24+
if (low[i] >= tin[node]) {
25+
bccs.push_back(vector<int>());
26+
int lst = -1;
27+
do {
28+
bccs.back().push_back(stck.back());
29+
lst = stck.back();
30+
stck.pop_back();
31+
} while (!stck.empty() && lst != i);
32+
bccs.back().push_back(node);
33+
}
34+
}
35+
}
36+
}
37+
38+
int main() {
39+
ios_base::sync_with_stdio(0);
40+
cin.tie(0);
41+
ifstream cin("biconex.in");
42+
ofstream cout("biconex.out");
43+
44+
int n, m;
45+
cin >> n >> m;
46+
FOR(i, 0, m) {
47+
int u, v;
48+
cin >> u >> v;
49+
graph[u].push_back(v);
50+
graph[v].push_back(u);
51+
}
52+
dfs();
53+
54+
cout << bccs.size() << '\n';
55+
for (vector<int> i : bccs) {
56+
for (int j : i) cout << j << ' ';
57+
cout << '\n';
58+
}
59+
return 0;
60+
}

0 commit comments

Comments
 (0)