Skip to content

Commit c795b42

Browse files
Merge branch 'master' into city-attractions-upd
2 parents 53c5bf0 + 6a7b3ae commit c795b42

37 files changed

+2535
-575
lines changed

.github/workflows/update-usaco.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ jobs:
4747
pre-commit install
4848
env:
4949
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
50-
- name: Update contest to points
51-
run: |
52-
pip install -r src/components/markdown/ProblemsList/DivisionList/scripts/requirements.txt
53-
python src/components/markdown/ProblemsList/DivisionList/scripts/update.py -s $(( $(date +%y) - 1 )) -e $(date +%y)
50+
# - name: Update contest to points
51+
# run: |
52+
# pip install -r src/components/markdown/ProblemsList/DivisionList/scripts/requirements.txt
53+
# python src/components/markdown/ProblemsList/DivisionList/scripts/update.py -s $(( $(date +%y) - 1 )) -e $(date +%y)
5454
- name: Build list of problem ids
5555
run: |
5656
yarn

content/2_Bronze/Complete_Rec.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,7 @@ appear much less frequently than they once did.
11731173
11741174
```cpp
11751175
vector<int> perm(n);
1176+
iota(begin(perm), end(perm), 1);
11761177
do {
11771178
} while (next_permutation(begin(perm), end(perm)));
11781179
```

content/3_Silver/Conclusion.problems.json

+27-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@
7171
"isStarred": false,
7272
"tags": ["Connected Components", "DSU"],
7373
"solutionMetadata": {
74-
"kind": "autogen-label-from-site",
75-
"site": "CF"
74+
"kind": "internal"
7675
}
7776
},
7877
{
@@ -293,6 +292,19 @@
293292
"site": "CF"
294293
}
295294
},
295+
{
296+
"uniqueId": "cf-2021C2",
297+
"name": "Adjust The Presentation",
298+
"url": "https://codeforces.com/problemset/problem/2021/C2",
299+
"source": "CF",
300+
"difficulty": "Normal",
301+
"isStarred": false,
302+
"tags": ["Greedy"],
303+
"solutionMetadata": {
304+
"kind": "autogen-label-from-site",
305+
"site": "CF"
306+
}
307+
},
296308
{
297309
"uniqueId": "cf-700B",
298310
"name": "Connecting Universities",
@@ -369,6 +381,19 @@
369381
"site": "CF"
370382
}
371383
},
384+
{
385+
"uniqueId": "cf-2064D",
386+
"name": "Eating",
387+
"url": "https://codeforces.com/problemset/problem/2064/D",
388+
"source": "CF",
389+
"difficulty": "Hard",
390+
"isStarred": false,
391+
"tags": ["2D Prefix Sums", "Bitmasking", "DP"],
392+
"solutionMetadata": {
393+
"kind": "autogen-label-from-site",
394+
"site": "CF"
395+
}
396+
},
372397
{
373398
"uniqueId": "cf-1943C",
374399
"name": "Tree Compass",

content/3_Silver/More_Prefix_Sums.problems.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
"isStarred": false,
5757
"tags": ["Difference Array"],
5858
"solutionMetadata": {
59-
"kind": "autogen-label-from-site",
60-
"site": "CF"
59+
"kind": "internal"
6160
}
6261
},
6362
{
@@ -115,15 +114,14 @@
115114
},
116115
{
117116
"uniqueId": "cf-104114N",
118-
"name": "Nusret Gokce",
117+
"name": "Nusret Gökçe",
119118
"url": "https://codeforces.com/gym/104114/problem/N",
120119
"source": "CF",
121120
"difficulty": "Normal",
122121
"isStarred": false,
123122
"tags": ["Prefix Sums"],
124123
"solutionMetadata": {
125-
"kind": "autogen-label-from-site",
126-
"site": "CF"
124+
"kind": "internal"
127125
}
128126
},
129127
{

content/4_Gold/Conclusion.problems.json

+13
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,19 @@
278278
"site": "AC"
279279
}
280280
},
281+
{
282+
"uniqueId": "cf-2021E2",
283+
"name": "Digital Village (Hard Version)",
284+
"url": "https://codeforces.com/contest/2021/problem/E2",
285+
"source": "CF",
286+
"difficulty": "Hard",
287+
"isStarred": false,
288+
"tags": ["DSU", "DP"],
289+
"solutionMetadata": {
290+
"kind": "autogen-label-from-site",
291+
"site": "CF"
292+
}
293+
},
281294
{
282295
"uniqueId": "cf-1713E",
283296
"name": "Cross Swapping",

content/4_Gold/DP_Bitmasks.mdx

+112-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
id: dp-bitmasks
33
title: 'Bitmask DP'
4-
author: Michael Cao, Siyong Huang
4+
author: Michael Cao, Siyong Huang, Peng Bai
55
contributors: Andrew Wang, Neo Wang
66
prerequisites:
77
- intro-bitwise
@@ -72,6 +72,7 @@ $$
7272

7373
where $S \setminus \{i\}$ is the subset $S$ without city $i$.
7474

75+
**Time Complexity:** $\mathcal{O}(2^N \cdot N^2)$
7576
<LanguageSection>
7677

7778
<CPPSection>
@@ -173,7 +174,117 @@ print(dp[(1 << n) - 1][n - 1])
173174
```
174175

175176
</PySection>
177+
</LanguageSection>
178+
179+
## Merging Subsets
180+
181+
In some problems, for a set $S$, it is not sufficient to transition from $S \setminus \{i\}$.
182+
Instead, it is necessary to transition from all *strict* subsets of $S$.
183+
184+
Though it may seem like we have to do $\mathcal{O}(2^N \cdot 2^N) = \mathcal{O}(4^N)$ transitions,
185+
theres really only $\mathcal{O}(3^N)$ transitions!
186+
187+
To see why, let's count the number of ordered pairs $(T, S)$ where $T \subset S$.
188+
Instead of counting directly, notice that each element $x$ is either:
189+
1. In $T$ and $S$
190+
2. In neither
191+
3. In $S$ but not in $T$.
192+
If $x$ is in $T$ but not in $S$, $T$ isn't a valid subset.
193+
194+
Given that each element can be in three possible states, our overall complexity is actually $\mathcal{O}(3^N)$.
195+
196+
To implement this, we can do some bitwise tricks:
197+
<LanguageSection>
198+
<CPPSection>
199+
200+
```cpp
201+
for (int mask = 0; mask < (1 << n); mask++) {
202+
for (int submask = mask; submask != 0; submask = (submask - 1) & mask) {
203+
int subset = mask ^ submask;
204+
// do whatever you need to do here
205+
}
206+
}
207+
```
208+
209+
</CPPSection>
210+
</LanguageSection>
211+
212+
When we subtract $1$ from $\texttt{submask}$, the rightmost bit flips to a $0$ and all bits to the right of it will become $1$.
213+
Applying the bitwise AND with $\texttt{mask}$ removes all extra bits not in $\texttt{mask}$.
214+
From this process, we can get all strict subsets in increasing order by calculating $\texttt{mask} \oplus \texttt{submask}$, which does set subtraction.
215+
216+
<FocusProblem problem="sam2" />
217+
218+
### Explanation
219+
220+
The goal of this problem is to partition the nodes into sets such that the nodes in each set form a complete graph.
221+
Let $\texttt{dp}[S]$ be the minimum number of partitions such that in each partition, the graph formed is a complete graph.
222+
223+
We can first find which sets $T$ form a complete graph, setting $\texttt{dp}[T]$ to $1$ and $\infty$ otherwise.
224+
This can be done naively in $\mathcal{O}(2^N \cdot N^2)$ or $\mathcal{O}(2^N \cdot N)$
225+
by setting the adjacency list as a bitmask and using bit manipulations if a set of nodes is a complete graph.
226+
227+
Then we can transition as follows:
228+
$$
229+
\texttt{dp}[S] = \min_{T \subset S} (\texttt{dp}[T] + \texttt{dp}[S \setminus T])
230+
$$
231+
232+
### Implementation
176233

234+
**Time Complexity:** $\mathcal{O}(3^N + 2^N \cdot N)$
235+
236+
<LanguageSection>
237+
<CPPSection>
238+
239+
```cpp
240+
#include <bits/stdc++.h>
241+
using namespace std;
242+
243+
int main() {
244+
int n, m;
245+
cin >> n >> m;
246+
vector<int> adj(n);
247+
for (int i = 0; i < m; i++) {
248+
int u, v;
249+
cin >> u >> v;
250+
u--;
251+
v--;
252+
// adjacency list represented as a bitmask
253+
adj[u] |= (1 << v);
254+
adj[v] |= (1 << u);
255+
}
256+
257+
vector<int> dp(1 << n, INT32_MAX);
258+
for (int mask = 0; mask < (1 << n); mask++) {
259+
bool connected = true;
260+
for (int u = 0; u < n; u++) {
261+
if (((mask >> u) & 1) != 0) {
262+
// check if u is connected to all other nodes in mask
263+
if (((adj[u] | (1 << u)) & mask) != mask) {
264+
connected = false;
265+
break;
266+
}
267+
}
268+
}
269+
270+
if (connected) { dp[mask] = 1; }
271+
}
272+
273+
for (int mask = 0; mask < (1 << n); mask++) {
274+
for (int submask = mask; submask; submask = (submask - 1) & mask) {
275+
int subset = mask ^ submask;
276+
// submask has everything in mask but not in subset
277+
if (dp[subset] != INT32_MAX && dp[submask] != INT32_MAX) {
278+
dp[mask] = min(dp[mask], dp[subset] + dp[submask]);
279+
}
280+
}
281+
}
282+
283+
cout << dp[(1 << n) - 1] << endl;
284+
}
285+
```
286+
287+
</CPPSection>
177288
</LanguageSection>
178289
179290
### Problems

content/4_Gold/DP_Bitmasks.problems.json

+27
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@
1414
}
1515
}
1616
],
17+
"sam2": [
18+
{
19+
"uniqueId": "ac-CloseGroup",
20+
"name": "Close Group",
21+
"url": "https://atcoder.jp/contests/abc187/tasks/abc187_f",
22+
"source": "AC",
23+
"difficulty": "Easy",
24+
"isStarred": false,
25+
"tags": ["Bitmasks"],
26+
"solutionMetadata": {
27+
"kind": "none"
28+
}
29+
}
30+
],
1731
"general": [
1832
{
1933
"uniqueId": "ac-matching",
@@ -27,6 +41,19 @@
2741
"kind": "internal"
2842
}
2943
},
44+
{
45+
"uniqueId": "ac-grouping",
46+
"name": "Grouping",
47+
"url": "https://atcoder.jp/contests/dp/tasks/dp_u",
48+
"source": "AC",
49+
"difficulty": "Easy",
50+
"isStarred": false,
51+
"tags": ["Bitmasks", "DP"],
52+
"solutionMetadata": {
53+
"kind": "autogen-label-from-site",
54+
"site": "AC"
55+
}
56+
},
3057
{
3158
"uniqueId": "cf-1316E",
3259
"name": "Team Building",

content/4_Gold/DP_Ranges.mdx

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ redirects:
1111
- /plat/dp-ranges
1212
---
1313

14-
<!-- https://codeforces.com/contest/1312/problem/E -->
1514

1615
## Tutorial
1716

content/4_Gold/DP_Ranges.problems.json

+13
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@
101101
"site": "CF"
102102
}
103103
},
104+
{
105+
"uniqueId": "cf-1312E",
106+
"name": "Array Shrinking",
107+
"url": "https://codeforces.com/contest/1312/problem/E",
108+
"source": "CF",
109+
"difficulty": "Normal",
110+
"isStarred": false,
111+
"tags": ["Range DP"],
112+
"solutionMetadata": {
113+
"kind": "autogen-label-from-site",
114+
"site": "CF"
115+
}
116+
},
104117
{
105118
"uniqueId": "sapo-14-genghis",
106119
"name": "2014 - The Stables of Genghis Khan",

0 commit comments

Comments
 (0)