Many thanks to BledDest for the excellent problem set. However, the last two problems are quite difficult for me to solve. Therefore, I am sharing my thoughts on the first five problems.
2051A — Preparing for the Olympiad
Focus on the fact that Monocarp can freely choose his training days, but Stereocarp is forced to train the day after Monocarp. Monocarp should carefully pick days where the problems he solves outweigh those Stereocarp would solve the following day.
To maximize $$$m - s$$$, Monocarp should always train on the last day, as it contributes $$$a_n$$$ without affecting Stereocarp. For earlier days, Monocarp should train on day $$$i$$$ only if $$$a_i > b_{i+1}$$$, adding the difference $$$a_i - b_{i+1}$$$ to the total. This greedy approach ensures that Monocarp maximizes his problems solved while minimizing Stereocarp's. Iterate through the array once for each test case, adding valid differences and always including $$$a_n$$$ from the last day.
Time Complexity: $$$O(n)$$$ per test case
Space Complexity: $$$O(n)$$$
#include <bits/stdc++.h>
using namespace std;
void solve () {
int n;
cin >> n;
vector<int> a(n), b(n);
for (int &i : a) cin >> i;
for (int &i : b) cin >> i;
int res = 0;
for (int i = 0; i < n - 1; i++) {
res += max(0, a[i] - b[i + 1]);
}
cout << res + a.back() << endl;
}
int32_t main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
Monocarp's walking pattern repeats every three days, with distances $$$a$$$, $$$b$$$, and $$$c$$$. To find the day he completes his journey, calculate how many complete $$$3$$$-day cycles he can finish before walking at least $$$n$$$ kilometers.
The total distance Monocarp walks in one $$$3$$$-day cycle is $$$a + b + c$$$. First, calculate how many complete cycles he can walk, which is
Subtract the distance covered by these cycles from $$$n$$$ to find the remaining distance $$$n_{\text{rem}}$$$. If $$$n_{\text{rem}} = 0$$$, he finishes at the end of a complete cycle, i.e., on day $$$3 \times \text{cycles}$$$. Otherwise, determine the day within the next cycle by checking if $$$n_{\text{rem}}$$$ is covered by $$$a$$$, $$$a + b$$$, or $$$a + b + c$$$, corresponding to days $$$1$$$, $$$2$$$, or $$$3$$$ of the partial cycle. Finally, the result is
Time Complexity: $$$O(1)$$$ per test case
Space Complexity: $$$O(1)$$$
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve () {
int n, a, b, c;
cin >> n >> a >> b >> c;
int res = n / (a + b + c);
n %= (a + b + c);
if (n == 0) cout << res * 3 << endl;
else if (a >= n) cout << res * 3 + 1 << endl;
else if (a + b >= n) cout << res * 3 + 2 << endl;
else cout << res * 3 + 3 << endl;
}
int32_t main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
2051C — Preparing for the Exam
The problem revolves around checking if Monocarp knows all the questions in each list. Observe that each list has to miss less than two questions.
If $$$k + 1 < n$$$, it is impossible for Monocarp to pass any list, because he cannot know $$$n-1$$$ questions simultaneously. Output $$$m$$$ zeros.
If $$$k = n$$$, Monocarp knows all questions, so he passes every list. Output $$$m$$$ ones.
Otherwise, sort the known questions $$$q_1, q_2, \dots, q_k$$$. For each $$$a_i$$$, check if $$$a_i$$$ is in the sorted list of known questions. If $$$a_i$$$ is known, Monocarp cannot pass this list, so append '0' to the result. Otherwise, append '1'.
Time Complexity: $$$O(k \log k + m \log k)$$$ per test case
Space Complexity: $$$O(m + k)$$$
#include <bits/stdc++.h>
using namespace std;
void solve () {
int n, m, k;
cin >> n >> m >> k;
vector<int> a(m), q(k);
for (int i = 0; i < m; i++) {
cin >> a[i];
}
for (int i = 0; i < k; i++) {
cin >> q[i];
}
if (k + 1 < n) {
cout << string(m, '0') << endl;
} else if (k == n) {
cout << string(m, '1') << endl;
} else {
sort(q.begin(), q.end());
string res;;
for (int i = 0; i < m; i++) {
if (binary_search(q.begin(), q.end(), a[i])) {
res += '0';
} else {
res += '1';
}
}
cout << res << endl;
}
}
int32_t main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
To determine the number of interesting pairs, observe that removing elements at positions $$$i$$$ and $$$j$$$ leaves a sum of $$$S - a_i - a_j$$$, where $$$S$$$ is the total sum of the array.
First, compute the total sum $$$S = \text{sum}(a)$$$. The condition for an interesting pair translates to $$$l \leq a_i + a_j \leq r$$$, where $$$l = S - y$$$ and $$$r = S - x$$$. Sort the array to facilitate efficient pair counting. For each $$$a_i$$$, use binary search to find the range of indices $$$j > i$$$ where $$$a_i + a_j$$$ satisfies the bounds $$$[l, r]$$$. Specifically, use $$$\text{lower_bound}$$$ to find the first $$$a_j \geq l - a_i$$$ and $$$\text{upper_bound}$$$ to find the first $$$a_j > r - a_i$$$. The difference between these indices gives the number of valid pairs for the current $$$i$$$. Iterate through all $$$i$$$ to compute the total count efficiently. This approach, combining sorting and binary search, ensures the solution is fast enough for the input constraints.
Time Complexity: $$$O(n \log n)$$$ per test case
Space Complexity: $$$O(n)$$$
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve () {
int n, x, y;
cin >> n >> x >> y;
vector<int> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i];
}
int sum = accumulate(v.begin(), v.end(), 0LL);
sort(v.begin(), v.end());
int l = sum - y, r = sum - x, cnt = 0;
for (int i = 0; i < n; i++) {
int a = upper_bound(v.begin() + i + 1, v.end(), r - v[i]) - v.begin();
int b = lower_bound(v.begin() + i + 1, v.end(), l - v[i]) - v.begin();
cnt += a - b;
}
cout << cnt << endl;
}
int32_t main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
The key is to consider all possible tree prices. For each price, determine how many customers will buy trees and how many negative reviews will be received. Notice that the possible tree prices are limited to the values in arrays $$$a$$$ and $$$b$$$.
To solve the problem efficiently, treat each customer as contributing two potential price points: $$$a_i$$$ (positive review) and $$$b_i$$$ (negative review). Create a list of events where each $$$a_i$$$ adds a potential negative review, and each $$$b_i$$$ removes a potential buyer. Sort these events by price to process them in ascending order. Maintain a running count of total buyers and negative reviews, and for each price, calculate the store's total earnings. Only consider prices where the number of negative reviews does not exceed $$$k$$$. The maximum earnings across all valid prices give the result.
Time Complexity: $$$O(n \log n)$$$ per test case
Space Complexity: $$$O(n)$$$
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve () {
int n, k;
cin >> n >> k;
vector<int> a(n), b(n);
for (int &i : a) cin >> i;
for (int &i : b) cin >> i;
vector<pair<int, int>> res;
for (int i = 0; i < n; i++) {
res.emplace_back(a[i], 1);
res.emplace_back(b[i], 2);
}
sort(res.begin(), res.end());
int cnt = n, tmp = 0, ans = 0;
for (int i = 0; i < 2 * n; i++) {
int j = res[i].first;
if (tmp <= k) ans = max(ans, j * cnt);
while (n * 2 > i && res[i].first == j) {
tmp += (res[i].second == 1) - (res[i].second == 2);
cnt -= (res[i].second == 2);
i++;
}
i--;
}
cout << ans << endl;
}
int32_t main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
Hints are awesome.
-Thank you fo mach
Bhai complexityr jonno catagory na koira Tutorialer niche diya dile valo hoi.
There's a $$$\mathcal{O}(m + q)$$$ solution for C. Case where $$$n - k$$$ is 0, or $$$n - k > 1$$$ is handled similarly for yours, however, for $$$n - k = 1$$$, we'll do things a bit differently. Since we know that $$$q$$$ contains of $$$k$$$ distinct integers that should sum up to $$$n$$$, but there's one missing integer, the missing integer will be $$$x = \sum\limits_{i=1}^n i - \sum\limits_{i=1}^k q_i = \frac{n * (n - 1)}{2} - \sum\limits_{i=1}^k q_i$$$, so the answer will be 1 for $$$i$$$ which $$$a_i = x$$$ and 0 otherwise
It's a creative and interesting solution. Thank you for sharing it with me.
That's really intuitive and interesting .
There is a simple binary search solution for E too.
Check my submission
298020385
Solved the fifth problem after seeing your hint. This hints make your editorials the best than the official one.
here is the solution for F [sorry it's pretty long for an editorial]
2051F - Joker
simulate the process, and see which positions are possible to be the joker.
except for some prefix and suffix there is at most one consecutive range around the first position of the joker ($$$m$$$) where it is possible to be the joker.
in which case we are 100% sure that the card which is moved is a joker?
as said in the hints the joker possible positions, are some prefix(define the last position of the prefix as $$$it1$$$), some suffix(define the first position of the suffix as $$$it4$$$), and some consecutive range around the first starting position $$$m$$$(we let the first position be $$$it2$$$, and the last one $$$it3$$$), the initial values : $$$it1 = 0, it4 = n+1, it2 = it3 = m$$$.
in each move we can take a card, and place it at the first position or the last position, at first our joker is at position $$$m$$$, then the selected card ($$$a_1$$$) has three different variations:
$$$1. a_1 < m$$$: in this variations the card we choose is behind the joker's initial position, if it goes to the first position it won't change anything, but if it goes to the last, our joker card is pushed backwards to the position $$$m-1$$$, after this, $$$it2$$$ is decreased by one.
$$$2. a_1 = m$$$: in this variations the card we choose is definitely the joker, so there will be no consecutive range so we will put $$$it2$$$ and $$$it3$$$ to some number (to know that if $$$it2$$$ and $$$it3$$$ are those numbers there is no consecutive range, or define a bool variable to check that, in my code i used $$$it2 = -1$$$ and $$$it3 = -2$$$ to do that). but after this the joker might be at the first position which means we increase $$$it1$$$ by one, and also joker might be in the last position, which means we will decrease $$$it4$$$ by one.
$$$3. a_1 > m$$$: like the first one, but this time if the card goes to the beginning, our joker card might go to $$$m+1$$$, so after this $$$it3$$$ is increased.
ok now after the first query, there is no way we are 100% sure that the joker is selected. ok now for all $$$i$$$ ($$$i > 1$$$) we have 4 variations possible for the card:
$$$1. a_i \leq it1$$$ : this means there is a chance for the card to be joker, and it is also possible for it to not be the joker, if it is a joker then moving it to the first position doesn't change anything and moving it to the last, only matters when there is no suffix ($$$it4 = n+1$$$) in that case $$$it4$$$ is decreased by one, if it isn't a joker, still moving it to the first position doesn't change anything, and moving it to the last only matter when there is, a suffix ($$$it4 \neq n+1$$$), in that case $$$it4$$$ is decreased by one, also if there exist a consecutive range $$$it2$$$ is also decreased by one.
$$$2. a_i \geq it4$$$ : pretty much the same as last one but everything in reverse
$$$3. a_i \geq it2, a_i \leq it3$$$ : this means the consecutive range exists and the card which has been taken is in that range, if it is a joker, the prefix matters when $$$it1 = 0$$$ and suffix matters when $$$it4 = n+1$$$, in these cases, the prefix and suffix length grow by one. and if it is not a joker then the prefix matters when $$$it1 \neq 0$$$ and suffix matters when $$$it4 \neq n+1$$$, in this case their length grow by one, so anyway the prefix and suffix will grow by one:
$$$4.$$$and lastly the variation where the selected card is not in the prefix, suffix or the consecutive range, in this variation, the prefix only grows when $$$it1 \neq 0$$$(there is a prefix) and suffix only grows when $$$it4 \neq n+1$$$(there is a suffix), and if there exists a consecutive range, there is two variations:
$$$1. a_i < it2$$$ : which then if the card is placed in the first position nothing changes and if it is placed in the last position it decreases $$$it2$$$ by one.
$$$2. a_i > it3$$$ : which is similar to the previous variation but everything reversed.
our result will be $$$it1 + (n + 1) - it4 + (it3 - it2 + 1)$$$, note that you should add $$$(it3 - it2 + 1)$$$ only if there exist a consecutive range: also after all of this we must check that the prefix, suffix, and consecutive range do not collide with each other, so we will do this,