The current problems are the original A A B C D E, respectively.
The idea for problem D came up after eating at Sushiro, and the idea for problem E came up after eating at McDonald's. However, Sushiro is not a buffet restaurant. :(
The intended solutions are short.
Some (very) strong testers couldn't solve E when testing, and that's why we gave E so much score.
2085A - Serval and String Theory
When $$$s$$$ is lexicographically equal to or greater than the reversal of $$$s$$$, is it possible to make $$$s$$$ universal by performing the operations?
If possible, what is the minimum number of the operations required to make $$$s$$$ universal?
Case 1. If $$$s$$$ contains only one kind of letter, the answer will be NO
.
Case 2. If $$$s$$$ is universal already, no operation is needed, and the answer will be YES
.
Otherwise, $$$s$$$ falls into the following Case 3.
Case 3.1. When $$$s$$$ is not a palindrome, one can make $$$s$$$ universal in one operation by swapping the first pair of different letters of $$$s$$$ and its reversal.
Case 3.2. When $$$s$$$ is a palindrome, swapping any two distinct letters will make $$$s$$$ no longer a palindrome. Note that the reversal of $$$s$$$ after the swap can be obtained by swapping the letters in the symmetric positions of the original $$$s$$$. Since either $$$s$$$ or its reversal is universal, the original $$$s$$$ can be made universal in one operation.
Thus, for Case 3, the answer will be NO
if no operation can be performed; otherwise, the answer will be YES
.
getint = lambda: int(input())
getints = lambda: map(int, input().split())
def solve():
n, k = getints()
s = input().strip()
if s < s[::-1] or (k >= 1 and min(s) != max(s)):
print('YES')
else:
print('NO')
t = getint()
for _ in range(t):
solve()
2085B - Serval and Final MEX
Before the last operation, what should the array be to obtain $$$0$$$?
How to make all the elements in the array non-zero?
Note that before the last operation, all the integers in the array should be positive. Thus, we aim to turn the zeroes in $$$a$$$ into non-zeroes. To achieve this, we split the given array $$$a$$$ into two halves and perform the operations on the halves that contain zeroes. After that, there will be no zeroes in either of the two halves. The final $$$0$$$ can be obtained by performing the last operation on the entire array.
In fact, the final element can be $$$0$$$ after the operations for any array of length $$$4$$$. Can you solve the problem under the constraint of $$$n=4$$$?
When $$$n>4$$$, you can perform the operation on any subarray of length $$$(n-3)$$$. After the operation, the array $$$a$$$ will contain only $$$4$$$ integers, which can be solved by brute force.
getint = lambda: int(input())
getints = lambda: map(int, input().split())
def solve():
n = getint()
a = list(getints())
op = []
mid, r = n // 2, n
if 0 in a[mid:]:
op.append([mid + 1, n])
r -= n - mid - 1
if 0 in a[:mid]:
op.append([1, mid])
r -= mid - 1
op.append([1, r])
print(len(op))
for o in op:
print(*o)
t = getint()
for _ in range(t):
solve()
2085C - Serval and The Formula
The formula $$$(x+k) + (y+k) = (x+k) \oplus (y+k)$$$ is equivalent to $$$(x+k) \mathbin{\&} (y+k) = 0$$$, where $$$\&$$$ denotes the bitwise AND operation.
Note that a power of $$$2$$$ shares no common bits with any positive integer less than it.
It can be shown that such an non-negative integer $$$k$$$ does not exist when $$$x=y$$$.
When $$$x\neq y$$$, one can show that $$$k = 2^n - \max(x, y)$$$ is a possible answer, where $$$2^n$$$ is a power of $$$2$$$ that is sufficiently large.
getint = lambda: int(input())
getints = lambda: map(int, input().split())
def solve():
x, y = getints()
if x == y:
print(-1)
else:
print(2 ** 48 - max(x, y))
t = getint()
for _ in range(t):
solve()
2085D - Serval and Kaitenzushi Buffet
Do not go for DP.
How many plates of sushi can be taken?
What are the constraints on the time of taking plates of sushi?
Note that the last $$$i$$$-th time taking a plate of sushi should be no later than the $$$(n - i\cdot(k+1) + 1)$$$-th minute. This constraint limits the time that a taking action can be performed. Therefore, we enumerate the $$$n$$$ minutes in chronological order, and greedily take the untaken plates delivered before with the greatest deliciousness when we reach a constraint, i.e., the current minute is the $$$(n - i\cdot(k+1) + 1)$$$-th minute for a certain $$$i$$$. The deliciousnesses of the untaken plates can be maintained by a heap. The total complexity is $$$O(n \log n)$$$.
#include <cstdio>
#include <queue>
using namespace std;
const int N = 2e5 + 5;
int n, k;
int d[N];
long long ans;
void solve() {
scanf("%d%d", &n, &k);
ans = 0;
priority_queue <int> q;
for (int i = 1; i <= n; i++) {
scanf("%d", &d[i]);
q.push(d[i]);
if ((n - i + 1) % (k + 1) == 0) {
ans += q.top();
q.pop();
}
}
printf("%lld\n", ans);
}
int main() {
int t;
scanf("%d", &t);
while (t--)
solve();
return 0;
}
2085E - Serval and Modulo
What happens when an integer $$$a_i$$$ mods $$$k$$$?
Note that the difference between $$$a_i$$$ and $$$b_i$$$ is a multiple of $$$k$$$.
The same holds for the difference between the sum of $$$a_i$$$ and the sum of $$$b_i$$$.
Notice that $$$d(n) \leq 2304$$$ holds for all $$$n \leq 10^{10}$$$, where $$$d(n)$$$ denotes the number of divisors of $$$n$$$.
Note that if such a magic number $$$k$$$ exists, it will be a divisor of $$$\Delta = \sum a_i - \sum b_i$$$ when $$$\Delta \neq 0$$$, or it can be any integer greater than all the $$$a_i$$$. Thus, we can check all the divisors of $$$\Delta$$$, resulting in a solution of $$$O\left(\sum (n \cdot d(\sum a_i) + \sqrt{\sum a_i})\right)$$$ time, where $$$d(n)$$$ denotes the number of divisors of $$$n$$$.
#include <cstdio>
using namespace std;
const int N = 1e4 + 5;
const int C = 1e6 + 5;
int n;
int a[N], b[N];
int cnt[C];
long long s;
bool check(int k) {
for (int i = 1; i <= n; i++)
cnt[a[i] % k]++;
for (int i = 1; i <= n; i++)
if (--cnt[b[i]] < 0) {
cnt[b[i]] = 0;
for (int i = 1; i <= n; i++)
cnt[a[i] % k] = 0;
return 0;
}
return 1;
}
void solve() {
scanf("%d", &n);
s = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
s += a[i];
}
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
s -= b[i];
}
if (s == 0) {
printf("%d\n", check(0xc0ffee) ? 0xc0ffee : -1);
return;
}
for (int i = 1; 1ll * i * i <= s; i++)
if (s % i == 0) {
if (check(i)) {
printf("%d\n", i);
return;
}
if (i < C && check(s / i)) {
printf("%d\n", (int)(s / i));
return;
}
}
printf("-1\n");
}
int main() {
int t;
scanf("%d", &t);
while (t--)
solve();
return 0;
}
2085F1 - Serval and Colorful Array (Easy Version)
Consider the integers in the colorful subarray after swapping.
How to gather these integers together, forming a colorful subarray, with the minimum number of swaps?
Consider the middle one among all the the elements in the colorful subarray.
Consider the elements in the colorful subarray after swapping. The first observation is as follows.
Observation. Mark the elements in the colorful subarray. Before swapping, to make these marked elements continuous, gathering them toward the middle one among them minimizes the number of swaps.
Proof. It is not optimal to swap two marked elements. Thus, the leftmost $$$x$$$ elements will move to their right, and the rightmost $$$(k-x)$$$ elements will move to their left. They will meet at some point between the $$$x$$$-th element and the $$$(x+1)$$$-th element. If $$$x < {k\over 2}$$$, adjusting the meeting point to its right reduces $$$(k-x)-x > 0$$$ swaps. If $$$x > {k\over 2}$$$, we can adjust it to its left and reduce the number of swaps similarly. Therefore, one can show that setting the meeting point to the middle of them is optimal through adjustments. $$$\square$$$
From the observation we can also conclude that, the minimum number of swaps required to make the marked elements continuous is the difference between the sum of the distances from each marked element to the middle position before swapping and that sum after swapping, if the marked elements are swapped toward the middle position. Notice that the latter sum is a fixed constant only related to $$$k$$$.
Focusing on the middle position of the colorful subarray, we enumerate all the positions in the array as possible middle positions. For each possible middle position $$$p$$$, to form the colorful subarray whose middle position is $$$p$$$, we should choose $$${k\over 2}$$$ distinct integers from its left and the other $$$k\over 2$$$ from its right. The rounding of $$$k\over 2$$$ will not affect the correctness as long as the sum of the rounded numbers is $$$k$$$.
For each $$$1\leq i\leq k$$$, we should determine whether $$$i$$$ should be chosen from the left side of $$$p$$$ or the right side of $$$p$$$. Let the distance from $$$p$$$ to the rightmost integer $$$i$$$ on its left be $$$l_i$$$, and the distance for the right side be $$$r_i$$$. We should choose either $$$l_i$$$ or $$$r_i$$$ for each $$$i$$$ under the constraint that both the number of chosen $$$l_i$$$ and that of $$$r_i$$$ are $$$k\over 2$$$, minimizing the sum of the distances we choose. This can be done by first forcing to choose all the $$$l_i$$$, and then choosing the smallest $$$k\over 2$$$ elements of $$$(r_i-l_i)$$$ greedily.
In implementation, when enumerating the middle position $$$p$$$, both $$$l_i$$$ and $$$r_i$$$ can be simply calculated in $$$O(n)$$$ time, and then sort $$$(r_i - l_i)$$$ in $$$O(n\log n)$$$ time. The total complexity is $$$O(n^2\log n)$$$.
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 3005;
const long long oo = 1e18;
int n, k;
int a[N], l[N], r[N], d[N];
long long ans;
void solve() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
ans = oo;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k; j++)
l[j] = r[j] = n + 1;
for (int j = i; j; j--)
l[a[j]] = min(l[a[j]], i - j);
for (int j = i; j <= n; j++)
r[a[j]] = min(r[a[j]], j - i);
long long s = 0;
for (int j = 1; j <= k; j++) {
s += l[j];
d[j] = r[j] - l[j];
}
sort(d + 1, d + k + 1);
for (int j = 1; j <= (k + 1) / 2; j++)
s += d[j];
ans = min(ans, s);
}
for (int i = 1; i <= k; i++)
ans -= abs(i - (k + 1) / 2);
printf("%lld\n", ans);
}
int main() {
int T;
scanf("%d", &T);
while (T--)
solve();
return 0;
}
2085F2 - Serval and Colorful Array (Hard Version)
Is it possible to simplify the constraints?
Is it possible to remove the constraint that exactly $$$k\over 2$$$ elements should be chosen from both sides of the enumerated position?
Optimizing the solution of F1 using (possibly, heavy) data structures results in a $$$O(n\log n)$$$ solution.
Here we introduce a linear approach for F2 came up by Error_Yuan. In fact, the following proposition holds.
Proposition. The answer obtained is still correct without the constraint that exactly $$$k\over 2$$$ elements should be chosen from both sides of the enumerated position.
Without the constraint, when enumerating the position $$$p$$$, we can directly choose the smaller one between $$$l_i$$$ and $$$r_i$$$ for each $$$1\leq i\leq k$$$.
Proof. On the one hand, notice that the distance sum will not be smaller when $$$p$$$ is not the middle position among the chosen elements. On the other hand, consider the colorful subarray that produces the optimal answer, and mark the elements in it first. When $$$p$$$ enumerates to the middle position of the marked elements before swapping, the minimal distance sum without the constraint is no greater than that under the constraint. Therefore, all the considered candidates are no less than the real answer, and the real answer can be reached, completing the proof. $$$\square$$$
In implementation, we consider the contribution to each position $$$p$$$ for each integer $$$1\leq i\leq k$$$. For a certain $$$i$$$, it can be shown that the delta of the contribution will be one of $$$-1$$$, $$$0$$$, or $$$+1$$$ when $$$p$$$ moves to an adjacent position. The delta of the contribution remains unchanged for most positions, and only changes either at the position where $$$i$$$ placed, or at the midpoint between two adjacent $$$i$$$. By pre-calculating the changes of contribution deltas over all the $$$i$$$ and performing the prefix sum on the array twice, we can obtain the distance sums, resulting in an $$$O(n)$$$ solution.
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 4e5 + 5;
const long long oo = 1e18;
int n, k;
int a[N];
int last[N], dd[N];
long long s, d, ans;
void solve() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
last[i] = dd[i] = 0;
s = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (!last[a[i]])
s += i - 1;
else {
int pre = last[a[i]];
int mid = (pre + i) / 2;
if ((pre + i) & 1) {
dd[mid]--;
dd[mid + 1]--;
} else
dd[mid] -= 2;
}
dd[i] += 2;
last[a[i]] = i;
}
ans = oo;
d = -k;
for (int i = 1; i <= n; i++) {
ans = min(ans, s);
d += dd[i];
s += d;
}
for (int i = 1; i <= k; i++)
ans -= abs(i - (k + 1) / 2);
printf("%lld\n", ans);
}
int main() {
int T;
scanf("%d", &T);
while (T--)
solve();
return 0;
}
Nice contest!
If only Hint 1 was available for D during the contest , good problems overall.
got stuck on do optimization lol
First time ever I do have a feel I can solve problems in Div2D and Div2F1.
Great problem setting, thanks for the contest.
very weird that last div2 contest my rank was 419 and delta was 26... now my rank is lower 454 but delta is 33 ... I was expecting it to be 1 digit or maybe negative.
but I am ok with this... ha ha
That is basically because this round have 35k registration.
ok, I understand, thanks
Furthermore, your last div2 (round 1008) was separated from div1, so you weren't ranked with candidate master, that explain an other part of the difference
ok, I think I had a very simplistic view of ranking updates ( which was delta proportional to rank in the current contest only ) ... lot more to know for me
hint 1 for problem D feels like a personal attack, I spent quite some time thinking for DP solution lol.
Nice contest, Even more nice editorial. Thanks to the everyone involved.
yes, this editorial is very well presented, with hints given, which can help someone who wants to upsolve. kudos
You can easily solve D by going backwards in time and doing a regret greedy
Wow, regret greedy? Do you have a minute to explain what that is/provide an associated blog post that explains it? (after a quick search, I did not find any material on the matter)
A regret greedy is a greedy where you can exchange decisions from the past with more optimal decisions from the present
In D, you can swap a plate you took earlier for a more delicious plate now
I think the idea of regret greedy is that you don't have to take the optimal decision just yet, but later when it is not longer possible to postpone you will have all of the information to take a more optimal decision about the past/present. I don't know if that's what he meant but I also thought of this problem in a similar way. IMO you could also say that this problem resembles a job scheduling problem.
wow, I learn a new term today called "regret greedy"
Can you share a bit about the pattern of regret greedy, what "intuition" drive you to the regret greedy. Thank so much.
Serval please fix problem C's first hint !
thanks in advance!
UPD: Fixed!
Finally hit CM! Very enjoyable round imo (definitely not biased), peak problems.
orz sir!
yayy!!!
A nice contest with fast editorial!
Good contest with fast Editorial. The problems are interesting will try them all.
Solution to the C is out of the box, wow. i was able to get upto (x + K ) and (y + k) = 0. I think hard after this. but that was the wrong direction.
Yeah, same here! At first, I was trying to guess each bit of $$$k$$$ which just made the solution way more complicated than it needed to be. But after refining it, it finally got accepted! 311918873
I tried similar thing my solution is stuck on some 300th tc of 2nd tc. if it is not too much trouble can you please take a look at my code.
same here lol
How is this solution for B incorrect?
I am trying to break the array into two parts through
mid
, and I am checking for both parts. Whichever contains at least one0
, I apply the operation once on it.Then, I finally apply the operation on the leftover two elements (if the operations were applied on both parts, then we are left with two elements at the end, and they are not
0
).your code is not correct. for this input: n= 5, array = 1 2 3 4 0
output of your code: k = 2, l = 3 and r= 5, l = 1 and r = 4
after first operation length of your array becomes 3. but in 2nd operation how can you remove from 1 to 4?
Great contest, really enjoyed the problems.
can anyone explain d in dp format
D is a classic knapsack problem(Allowed maximum k operation to obtain maximum/minimum),In D you can think like this,you are gonna to choose i dishes and finish it,so the problem reduce to do i operation to obtain maximum d[i],sound like a knapsack problem right?But the classic knapsack problem got a O(n*k) time complexity in this problem k up to n so the worst case will become O(n^2) which will tle but knapsack problem got a effiency way is to use datastructure(HEAP),heap is a tree structure which root is always minimum/maximum(depend on which heap you use),so the idea is when you loop from right to left(from n-k to 1)(1-based) if you can freely choose a new element then choose it because this always increase your total d[i],but if you can't freely choose a element then you try to exchange the current d[i] with the deliciousness you had choose,because the previous deliciousness you had choose spent k+1 minute and the current d[i] also spent k+1 minute then you can directly exchange.311940708
i think E was much much easier than D and C, i did not even open it because of D
As frustrated as I am for not being able to solve Problem C, I am truly impressed and in awe by its solution. The feeling that yes, this is so very much interesting. Thank you for the contest and the concise solutions and this fast, well-prepared editorial.
Can someone explain D to me? that % one is not very intuitive
Let i = n-j(k+1)+1. Then we have n-i+1 = j(k+1), which is divided by k+1. i here is the position where we should determine which plate to take.
One of the best contests in a while , not many prerequisites and just logical stuff . And also the solutions are surprisingly short :pray:
serval my glorious king im honored to give a contest written by you
in problem A,can't i just swap s[0] with something smaller than s[0] from the string,or swap s[n-1] with something greater than s[n-1] when s[0]==s[n-1] and if k>0? like abba and k=1 so abab and k=0 thus abab is a universal string. can anyone point out the mistakes in my logic? and if s[0]>s[n-1] we will just swap s[0] with s[n-1] and need 1 operation and no operations are needed if s[0]<s[n-1]
The logic is correct; I don't see the issue.
but it gives wrong answer on testcase 2 ;(
If k>0 and the string does not consist of the same character, then the answer is always YES.
yes, also if the string is abcd and k=0 then the answer will also be YES right?because it is already universal. and if its dbca and k=1 i will just simply interchange s[0] with s[n-1] -abcd,so i dont exactly find any mistakes in my code.
Answer is YES unless: k=0 and r is not universal, or k>0 and r has only one distinct character
thats how I coded my solution look at my sol
can you find an edge case for my solution,its showing wrong answer on test case 2
Your code fails for the following test case:
Solution for C says "sufficient large" instead of "sufficiently large"
I absolutely hate these kinds of editorials, where the solution to a problem is written in 4 lines like — oh we can do this for the solution, then do that, then do this greedy approach which we won't explain how it is correct, and then finally find answer with some random data structure which we won't bother to implement. You might as well don't write the editorial please, it will make no difference.
You guys need to understand that a person who comes to the editorial, is expecting a detailed solution with good explanation, so that he/she can learn the idea behind it and use in future problems, and not a 4 line paragraph where half of the things are just written without any proofs or anything. Random people posting explanation in discussion thread are far better than these stupid editorials.
I feel you and I will suggest doing some competitions on codechef, they have really detailed editorials
also try to follow some YouTubers who analyze questions after the contest as they cover lower rated problems quite well. and then you can try to read editorials
That is what I do when I am not able to make sense of editorial, or I comment on the editorial post asking people for help and questions which are solved by large number of people generally get some explanation. so we can help each other and write different explanations in the comments
Can someone explain C again pls ?
$$$a$$$ ^ $$$b$$$ = $$$a$$$ + $$$b$$$ - $$$2$$$ * ($$$a$$$ & $$$b$$$) so the equation is $$$a$$$ + $$$b$$$ = $$$a$$$ + $$$b$$$ - $$$2$$$ * ($$$a$$$ & $$$b$$$) That means that ($$$a$$$ & $$$b$$$) = $$$0$$$ — ($$$x$$$ + $$$k$$$) & ($$$y$$$ + $$$k$$$) = $$$0$$$
We observe that a power of two is represented like that $$$10000...$$$ and any number before it doesn't have the most significant bit on so their ANDing will always be $$$0$$$. We want to add $$$k$$$ to both numbers such that the greater of them becomes a power of $$$2$$$ and the other one becomes less than it.
If both are equal then their ANDing after addition will never be 0. Otherwise, we can find the first $$$n$$$ such that $$$2^n$$$ >= $$$max(x, y)$$$ and make $$$k$$$ equal to $$$2^n$$$ - $$$max(x, y)$$$
Great explanation, thanks.
Repeating his explanation, we want the two final numbers to have bitwise AND AS 0. So, one way is, make one number as a power of 2, and the other number somewhat less than the first. Thus, they will have no set bit common.
Method: Add just enough to the greater of the two (max(x, y)), to make it a power of two. Since the two numebrs are different, the smaller number will also be smaller after adding k.
Code: 312044416
E was too much beautiful for proving me so dumb :(
us :(
Funnily enough I solved F1 without realizing you need $$$k/2$$$... and reading that hint was enough to solve F2. The data structure was not that heavy, you need a
multiset
for maintaining the smallest $$$k/2$$$ elements and another one for maintaining the remaining $$$k-k/2$$$.check(0xc0ffee)
Lol nice way to check for a random large mod in Solution for Eproblem D https://codeforces.me/contest/2085/submission/311937721
can someone explain to me why this code fails? tnx.
pretty good problem C , it has a pretty nice consructive solution https://codeforces.me/contest/2085/submission/311939672
Problem A with unclear meaning.
Loved solving (with a different approach) problem A! Video editorial link : https://youtu.be/yHD1pi2l2G0?si=s2hX91_CyHbdMn_-
surprising problem C solution, i was not expecting O(t).
I was trying to do bitmasks but failed
God editorial
2085D - Serval and Kaitenzushi Buffet Could someone please help me understanding what is wrong with my approach or code.
Approach:
While processing the time(0-index based) from n — 2(second last) to 0, I am trying to find out if I take the plate at time = i, then what is maximum sum of deliciousness of plates I can take at time > i, such that taking and consuming those plates (k + 1 for each plate) takes time <= n — 1 — (i + k), as this is the time left when I take plate i -> i + k time consumed. For that i am using a segment tree, in which I am storing for time = 0 to n, the (maximum sum of deliciousness, time) for each range processed by far.
Code:
Submission link: 311909974
Thanks in advance.
the editorial with hints are way better than others
Why account named AnotherAccount was banned?
he was caught cheating on problem a, see his submissions
If he/she were caught cheating, a star would appear above his/her submission.
but if you look in contest's there are 0 solves, he/she will be marked out of competition later.
Find me some equal solution.
you'll see the star later...
Does any $$$O(NK)$$$ solution for D exist? I have been thinking a lot on how to solve it and trying to see if anyone does to solve it, but it's either $$$O(N^2/K)$$$ or $$$O(N^2)$$$ (both of which I have did) or $$$O(N\log{N})$$$ (intended sol)
$$$K\leq \sqrt{N}$$$.
Name checks out