Hello, Codeforces!
Sorry for the late editorial. Our national olympiad just finished and we were sorting everything out.
We also apologize for weak tests on D that made an incorrect solution pass. Many testers submitted the same solution and we mistakenly thought that it was correct given the low bound on the number of batteries. Still, we hope that the contest was a fun and valuable experience for all contestants.
The editorial was prepared by efishel and me. If you have any questions about the problems or the solutions, please ask in the comments.
2155A - El fucho
When two teams in the same group face off against each other, exactly one of them stays in the group.
The answer for all $$$n$$$ is $$$2n-2$$$.
Let's consider the winners' group first. Note that exactly one team drops to the losers' bracket for every match in this group. Only one team is left in the winners' group right before the end, so $$$n-1$$$ matches must have been played in the winners' group right before the final match.
Similar logic applies to the losers' group. $$$n-1$$$ teams in total drop down to the losers' group over the course of the tournament. For every match played between two teams in this group, exactly one team is eliminated from the tournament. A single team in left in this group right before the final match, so $$$n-2$$$ matches must have been played in the losers' group right before the final match.
Finally, we add the final match to our calculation, bringing the total to
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, t;
cin >> t;
while(t--) {
cin >> n;
cout << 2*n-2 << "\n";
}
}
Alternatively, we can simulate the process directly.
Suppose there are $$$a$$$ teams in the winners' group and $$$b$$$ teams in the losers' group right before a round.
First, $$$\left \lfloor \frac{b}{2} \right \rfloor$$$ matches are played among the teams in the losers' group, so $$$\left \lfloor \frac{b}{2} \right \rfloor$$$ are eliminated in this step. We subtract this number from $$$b$$$ and add $$$\left \lfloor \frac{b}{2} \right \rfloor$$$ to the total number of matches played.
Then, $$$\left \lfloor \frac{a}{2} \right \rfloor$$$ matches are played among the teams in the winners' group, so $$$\left \lfloor \frac{a}{2} \right \rfloor$$$ of them drop down to the losers' group. We subtract this number from $$$b$$$ and add $$$\left \lfloor \frac{b}{2} \right \rfloor$$$ to the total number of matches played.
After simulating $$$\mathcal{O}(\log (n))$$$ rounds as described above, both brackets are left with a single team, so we add $$$1$$$ to our total.
Time complexity: $$$\mathcal{O}(\log (n))$$$
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, t, winners, losers, ans;
cin >> t;
while(t--) {
cin >> n;
winners = n;
losers = 0;
ans = 0;
while(max(losers, winners) > 1) {
ans += losers/2;
losers = (losers+1)/2;
ans += winners/2;
losers += winners/2;
winners++;
winners /= 2;
}
ans++;
cout << ans << "\n";
}
}
2155B - Abraham's Great Escape
There is exactly one value of $$$k$$$ that doesn't work
Two arrows facing each other trap Abraham forever.
We claim that the only value of $$$k$$$ for which the answer is $$$\texttt{NO}$$$ is $$$k = n*n-1$$$.
If $$$k = n^2-1$$$ were possible, Abraham should be trapped forever from exactly $$$n^2-(n^2-1) = 1$$$ starting cell, but the arrow in that cell would necessarily point towards the outside of the grid, or in the direction of another cell from which Abraham will eventually escape, so this situation is impossible and we should print $$$\texttt{NO}$$$.
All other values of $$$k$$$ are achievable with the following construction:
Fill up rows of the grid with $$$\texttt{U}$$$ from left to right and from top to bottom. You should place $$$k$$$ of this letter in total.
Fill every cell that doesn't have a $$$\texttt{U}$$$ already and isn't in the last row with a $$$\texttt{D}$$$. (These cells might be non-existent)
Fill the leftmost unoccupied cell in the last row with an $$$R$$$ and all the cells to its right with an $$$L$$$. (Note that at least one $$$L$$$ is placed).
This works because, if Abraham steps on a $$$\texttt{U}$$$, he will be pushed onto another $$$\texttt{U}$$$, and so on until he leaves the board.
On the other hand, if he steps on a $$$\texttt{D}$$$, he will be carried along all the way to an $$$\texttt{R}$$$ or $$$\texttt{L}$$$ in the last row. It's easy to see that these directions necessarily trap Abraham.
Time complexity: $$$\mathcal{O}(n^2)$$$
t = int(input())
for q in range(t):
n, k = (int(x) for x in input().split())
if(k == n*n-1):
print("NO")
else:
print("YES")
for i in range(n):
s = ""
for j in range(n):
if(k > 0):
s += "U"
k -= 1
elif(i == n-1 and j == n-1):
s += "L"
elif(i == n-1):
s += "R"
else:
s += "D"
print(s)
2155C - The Ancient Wizards' Capes
What's the maximum value that $$$|a_{i+1} - a_i|$$$ can attain for any $$$i$$$?
Bound the number of possible cape arrangements
Suppose that Harry's list corresponds to at least one arrangement of capes. The main claim is that any two consecutive values in his list differ by at most $$$1$$$.
Note that when Harry walks from position $$$i$$$ to position $$$i+1$$$, the visibility of wizard $$$1$$$ to $$$i-1$$$ and $$$i+2$$$ to $$$n$$$ is unaffected, so there are four possible situations regarding the other $$$2$$$ wizards:
Wizards $$$i$$$ and $$$i+1$$$ wear their capes to their left. Wizard $$$i+1$$$ becomes visible and wizard $$$i$$$ can still be seen from position $$$i+1$$$, so $$$a_{i+1}-a_i = 1$$$
Wizards $$$i$$$ and $$$i+1$$$ wear their capes to their right. Wizard $$$i+1$$$ remains visible while wizard $$$i$$$ becomes invisible from position $$$i+1$$$, so $$$a_{i+1}-a_i = -1$$$
Wizard $$$i$$$ wears his cape to his left while wizard $$$i+1$$$ wears his cape to his right. Both wizards are still visible from position $$$i+1$$$, so $$$a_{i+1}-a_i = 0$$$
Wizard $$$i$$$ wears his cape to his left while wizard $$$i+1$$$ wears his cape to his right. Wizard $$$i+1$$$ becomes visible, but wizard $$$i$$$ becomes invisible when moving to position $$$i+1$$$, so $$$a_{i+1}-a_i = 0$$$
In summary, if both wizards wear their capes the same way, the difference between the corresponding entries in Harry's list is $$$1$$$. Else, it is $$$0$$$. Note that this determines a unique possibility (it might be invalid) for the entire cape arrangement based on how wizard $$$1$$$ is wearing his cape only if $$$|a_{i+1}-a_i| \lt 2$$$ for all $$$1 \le i \lt n$$$.
Thus, there are at most two possible arrangements for the wizards' capes. We can construct both of them and check whether they are consistent with Harry's list.
Time complexity: $$$\mathcal{O}(n)$$$
def validar(x, n, a):
flag = False
visibles = 1
for i in range(2, n+1):
if(x[i] == 1):
visibles += 1
if(visibles == a[1]):
flag = True
for i in range(1, n):
if(x[i] == 1 and x[i+1] == 1):
visibles -= 1
elif(x[i] == 0 and x[i+1] == 0):
visibles += 1
if(a[i+1] != visibles):
flag = False
break
return flag
t = int(input())
for i in range(t):
sol1 = []
sol2 = []
sol1.append(0)
sol2.append(0)
sol1.append(0)
sol2.append(1)
flag = True
cont = 0
n = int(input())
arr = []
arr.append(0)
arr.extend(map(int, input().split()))
for j in range(1, n):
if(arr[j+1]-arr[j] > 1):
flag = False
break
if(arr[j+1]-arr[j] == 0):
sol1.append(1-sol1[j])
sol2.append(1-sol2[j])
else:
sol1.append(sol1[j])
sol2.append(sol2[j])
if(not flag):
print(0)
continue
if(validar(sol1, n, arr)):
cont += 1
if(validar(sol2, n, arr)):
cont += 1
print(cont)
2155D - Batteries
Place the batteries in order on a circumference.
If there are $$$a$$$ working batteries, can we bound the distance between some pair of them in terms of $$$n$$$ and $$$a$$$?
Arrange the batteries in clockwise order on a circumference such that the arc length between any two consecutive batteries is $$$1$$$, and let the indices of the working batteries be $$$1 \le b_1 \lt b_2 \lt \dots \lt b_a \le n$$$.
Let the distance between two working batteries $$$b_i$$$ and $$$b_{i+1}$$$ be $$$b_j-b_i$$$ if $$$i \lt a$$$ and $$$b_1+n-b_a$$$ if $$$i = a$$$. Note that this matches the length of a circle arc between $$$b_i$$$ and $$$b_{i+1}$$$ that doesn't contain any other working battery.
Observe that the sum of the distances between $$$b_i$$$ and $$$b_{i+1}$$$ for $$$1 \le i \le a$$$ (indices taken $$$\bmod a$$$) is exactly $$$n$$$, since the corresponding circle arcs make up the entire circumference. Since there are $$$a$$$ pairs of working batteries, by Pigeonhole Principle there is some distance that is less than or equal to $$$\left \lfloor \frac{n}{a} \right \rfloor$$$
Consequently, the following strategy works: For every $$$i$$$ from $$$1$$$ to $$$\left \lfloor \frac{n}{a} \right \rfloor$$$, and for every $$$j$$$ from $$$1$$$ to $$$n$$$, query batteries $$$j$$$ and $$$j+i \bmod n$$$ (if $$$j+i = 0$$$, query with battery $$$n$$$) which is equivalent to querying battery $$$j$$$ and the one $$$i$$$ positions ahead clockwise.
The above takes at most
trials, as desired.
#include <bits/stdc++.h>
using namespace std;
void main_() {
int n, x;
cin >> n;
for (int i = 1; i < n; i++)
for (int j = 1; j <= n; j++) {
x = (i+j)%n;
if(x == 0) {
x = n;
}
cout << j << " " << x << endl;
int res;
cin >> res;
if (res) {
return;
}
}
}
int main() {
int t = 1;
cin >> t;
while (t--)
main_();
return 0;
}
2155E - Mimo & Yuyu
When $$$n = 1$$$, the total number of turns is fixed.
When $$$n = 2$$$, the winning and losing states depend only on the parity of the amount of tokens in each column.
For convenience, let's denote with $$$d_i$$$ the number of tokens located in column $$$i$$$.
It's worth noting that the game lasts a finite amount of turns because, the array $$$[ d_m, d_{m-1}, \dots d_1 ]$$$ becomes lexicographically smaller (strictly) after each turn.
Note that we can think of each token independently, as tokens are only removed one at a time by the players.
We first deal with the case $$$n = 1$$$. Let $$$c_i$$$ be the column where token $$$i$$$ is located. We will prove by induction that token $$$i$$$ contributes $$$2^{c_i-2}$$$ turns to the game whenever $$$c_i \ge 2$$$. That is, $$$2^{c_i-2}$$$ turns are necessary and sufficient to remove token $$$i$$$ and all the tokens it spawns from the board.
Base case $$$c_i = 2$$$: A player moves token $$$i$$$ to column $$$1$$$. No tokens are added to the board, so $$$1 = 2^0$$$ turns are played in total.
Otherwise, $$$c_i-2$$$ tokens will be added to the board after choosing token $$$i$$$, one in each of columns $$$2, 3, \dots {c_i-1}$$$. By the induction hypothesis, removing these tokens and all the tokens they spawn will take
turns. Adding the initial turn to the total, we get $$$2^{c_i-2}-1+1 = 2^{c_i-2}$$$ turns in total.
The answer is equivalent to the parity of the number of turns performed in total, obtained by summing the contribution of turns by each token. Only tokens in column $$$2$$$ contribute an odd amount of turns ($$$2^0 = 1$$$ turn) while every other token contributes an even amount of turns ($$$0$$$ or $$$2^{j-2}$$$ turns), so we just need to print $$$\texttt{Mimo}$$$ if there is an odd number of tokens on column $$$2$$$ or $$$\texttt{Yuyu}$$$ if there is an even amount.
The only other case is when $$$n \ge 2$$$. We claim that the second player wins if and only if, for all $$$i \ge 2$$$,
- If $$$d_i = 0$$$ for all $$$i \ge 2$$$: The game is automatically a losing state.
- $$$d_i \equiv 0 \; \bmod 2$$$ for all $$$i \ge 2$$$ turns out to also be a losing state. Any move would cause some $$$d_j$$$ (in particular, $$$j = b_1$$$) to go from even to odd; thus, the opponent is given a winning game, as we will prove below.
We claim that $$$d_j \equiv 1 \; \bmod 2$$$ for some $$$j \ge 2$$$ is a winning state. Denote the maximum of all such $$$j$$$ as $$$j_{max}$$$. Our objective will be to give the opponent a game which falls under the first or second bullet point ($$$d_i \equiv 0 \; \bmod 2$$$ for all $$$i \ge 2$$$). If such a thing is always possible, after a finite amount of moves, the state given to the opponent will necessarily be exactly that of the first bullet point (the "minimal" losing state), proving these states are winning.
By definition of $$$j_{max}$$$, $$$d_i \equiv 0 \; \bmod 2$$$ for all ($$$i \gt j_{max}$$$). Performing a turn with chosen token $$$c$$$ in column $$$j_{max}$$$ causes $$$d_{j_{max}}$$$ to become $$$0 \bmod 2$$$. For all columns $$$i$$$ ($$$i \lt j_{max}$$$) a move that achieves $$$d_i \equiv 0 \; \bmod 2$$$ is as follows:
- If $$$d_i \equiv 0 \; \bmod 2$$$: Make sure $$$2$$$ tokens are added to column $$$i$$$.
- If $$$d_i \equiv 1 \; \bmod 2$$$: Make sure $$$1$$$ token is added to column $$$i$$$.
Such a move is possible because $$$n \ge 2$$$. This is an example of how it could look like:

Time complexity: $$$\mathcal{O}(k)$$$ or $$$\mathcal{O}(k\log m)$$$ depending on implementation.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector <ll>;
void tc () {
ll n, m, k;
cin >> n >> m >> k;
set <ll> st;
for (ll id = 0; id < k; id++) {
ll i, j;
cin >> i >> j;
if (j == 1) continue;
if (n == 1 && j != 2) continue;
if (st.count(j))
st.erase(j);
else
st.insert(j);
}
cout << (st.size() > 0 ? "Mimo" : "Yuyu") << '\n';
}
int main () {
cin.tie(nullptr) -> sync_with_stdio(false);
ll T; cin >> T; while (T--) { tc(); }
return 0;
}
2155F - Juan's Colorful Tree
Consider the graph formed by the vertices with color $$$x$$$ and the edges between them. What happens if a query contains two vertices in the one of this graph's connected components ("color components")?
After assigning IDs to each "color component" (for all colors), we can calculate the answer for two vertices by counting the number of components which contain both of them.
We can precompute the answer for all possible queries containing vertex $$$x$$$ with DFS.
Determining all answers with only one of the two aforementioned methods is very expensive. Is there some way to balance the complexity by using one over the other in certain situations?
There are some solutions with square-root complexity with an additional log factor that can pass if optimized enough, but we will present an $$$\mathcal{O}((n+q+s)\sqrt s)$$$ solution.
Let's first transform the problem from calculating the intersection of $$$C_w$$$ for all nodes $$$w$$$ in the path from $$$a_i$$$ to $$$b_i$$$ ($$$\left| C_{a_i} \cap \dots \cap C_{b_i} \right|$$$) to calculating the intersection of 2 sets: $$$D_{a_i}$$$ and $$$D_{b_i}$$$. We will calculate $$$\left|D_{a_i} \cap D_{b_i}\right|$$$ in average square-root complexity, using the best of 2 algorithms for each type of query.
First, let's define the sets $$$D_1, D_2, \dots D_n$$$. Let a maximal color component be a set of vertices, all of which contain some color $$$x$$$ in their sets, such that there is no other vertex with color $$$x$$$ adjacent to some vertex of the maximal component. We will assign an arbitrary ID to each maximal color component, and $$$D_u$$$ will contain the IDs of the maximal color components which node $$$u$$$ belongs to.
Note that $$$\left| D_u \right| = \left| C_u \right|$$$. Also note that the answer now is simply $$$\left|D_{a_i} \cap D_{b_i}\right|$$$. A possible $$$\mathcal{O}\left(n+s+k\right)$$$ algorithm calculating the sets $$$D_i$$$ is to maintain $$$k$$$ stacks while doing a DFS where, when visiting node $$$u$$$, stack $$$c$$$ contains the ancestors of node $$$u$$$ with color $$$c$$$. Checking the top of the stack suffices to know if a new component is created, or inherited from one's parent.
Here are 2 algorithms which calculate the cardinality of the intersection: One answers a query for a given pair of nodes $$$a_i$$$, $$$b_i$$$ and runs in $$$\mathcal{O}\left( |D_{a_i}|+|D_{b_i}| \right)$$$. The other calculates the answer between a fixed node $$$u$$$ and all $$$n$$$ nodes in $$$\mathcal{O}\left( n+s \right)$$$.
The first algorithm relies on sorting the sets $$$D_u$$$ (stored in lists or arrays), and then using the two-pointers technique to calculate the intersection of two sorted arrays in linear time. The second algorithm roots the tree in $$$u$$$ and starts a DFS, where the frequency of all $$$k$$$ colors across ancestors is maintained. For every node $$$v$$$, it calculates if the frequency of every color in $$$C_v$$$ is equal to its depth.
Let $$$B$$$ be a fixed integer. We precompute answers when $$$|D_u| \ge B$$$ using the $$$\mathcal{O}\left( n+s \right)$$$ algorithm. Otherwise, we use the $$$\mathcal{O}\left( |D_{a_i}|+|D_{b_i}| \right)$$$ algorithm for queries in which $$$|D_{a_i}|, |D_{b_i}| \le B$$$. The complexity of this approach is $$$\mathcal{O}\left( qB + (s/B)(n+s) \right)$$$ because there are at most $$$s/B$$$ vertices whose sets have a cardinality greater than $$$B$$$. Setting $$$B$$$ to be around $$$\sqrt s$$$, we get that our procedure runs in $$$\mathcal{O}\left(q\sqrt s + \sqrt s (n+s) \right) = \mathcal{O}\left( (n+q+s)\sqrt s \right)$$$.
Time complexity: $$$\mathcal{O}\left( (n+q+s)\sqrt s \right)$$$
Memory complexity: $$$\mathcal{O}\left( s + n\sqrt s \right)$$$
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector <ll>;
const ll MAXN = 3E5+16, B = 800;
vll adj[MAXN];
vll cols[MAXN], comps[MAXN];
ll comp_col[MAXN];
ll timer = 1, cur = 1;
ll last[MAXN];
bool active[MAXN];
ll curMap[MAXN];
int preProc[MAXN/B+16][MAXN];
void dfs1 (ll u, ll par) {
vll th(cols[u].size()), th2(cols[u].size());
comps[u].resize(cols[u].size());
for (ll i = 0; i < cols[u].size(); i++) {
ll c = cols[u][i];
th[i] = last[c];
th2[i] = comp_col[c];
comp_col[c] = (last[c] == par ? comp_col[c] : timer++);
comps[u][i] = comp_col[c];
last[c] = u;
}
for (ll v : adj[u]) {
if (v == par) continue;
dfs1(v, u);
}
for (ll i = 0; i < cols[u].size(); i++) {
ll c = cols[u][i];
last[c] = th[i];
comp_col[c] = th2[i];
}
}
void tc () {
ll n, k, s, q;
cin >> n >> k >> s >> q;
fill(adj, adj+n, vll({}));
for (ll i = 1; i < n; i++) {
ll u, v;
cin >> u >> v;
u--; v--;
adj[u].push_back(v);
adj[v].push_back(u);
}
timer = 1;
cur = 1;
fill(cols, cols+n, vll({}));
fill(comps, comps+n, vll({}));
fill(comp_col, comp_col+k, -16);
fill(last, last+k, -16);
for (ll i = 0; i < s; i++) {
ll x, c;
cin >> x >> c;
x--; c--;
cols[x].push_back(c);
}
dfs1(0, 0);
for (ll u = 0; u < n; u++) {
sort(comps[u].begin(), comps[u].end());
}
for (ll u = 0; u < n; u++) {
if (cols[u].size() < B) continue;
// >= B
for (ll c : comps[u]) active[c] = true;
for (ll v = 0; v < n; v++) {
preProc[cur][v] = 0;
for (ll c : comps[v]) {
preProc[cur][v] += active[c];
}
}
for (ll c : comps[u]) active[c] = false;
curMap[u] = cur++;
}
while (q--) {
ll u, v;
cin >> u >> v;
u--; v--;
if (cols[u].size() >= B) {
cout << preProc[curMap[u]][v] << ' ';
continue;
}
if (cols[v].size() >= B) {
cout << preProc[curMap[v]][u] << ' ';
continue;
}
ll ans = 0;
ll p1 = 0;
for (ll p2 = 0; p2 < comps[v].size(); p2++) {
while (p1 < comps[u].size() && comps[u][p1] < comps[v][p2]) p1++;
if (p1 == comps[u].size() || comps[u][p1] != comps[v][p2]) continue;
ans++;
}
cout << ans << ' ';
}
cout << '\n';
}
int main () {
cin.tie(nullptr) -> sync_with_stdio(false);
ll T; cin >> T; while (T--) { tc(); }
return 0;
}









Bricked D couldn't observe that. Good contest Nice problems. C is Nice
c was a fantastic problem
yes lol so true 100%% vedantk.
wow yar smart hai kya
MLA19 In problem D, what about the state of batteries not being constant. The batteries that were working in the beginning, do they always work and rest change ??
The positions of the batteries that work can change during the interaction. It might be more intuitive to think of the problem as "prove that $$$\left \lfloor \frac{n}{a} \right \rfloor$$$ trials are always enough to find a pair of working batteries without any sort of luck involved". That is, we are working with the worst case possible in a sense (in which we don't guess a pair we want on the first try by pure luck, for example).
The interactor guarantees that the underlying configuration of working batteries is consistent with the queries at every single step, so you could also think of it as interacting with the final configuration all along (to which the analysis in the editorial obviously applies).
Appreciate the reply.
But isn't it always possible to keep moving the non-working battery, for example n=20, a=19. At every d=1...(n-1) where d is the distance at which we're checking, we can make the "i+d" as non-working and rest as working.
Same doubt, please someone explain this
See my reply to codrac in this same thread.
No, it isn't, because the configuration of batteries has to be consistent with the information given at every step.
In your example (n = 20, a = 19), we query batteries 1 and 2. If the interactor replies that they don't turn the flashlight on, then either 1 or 2 has to be the non-working battery. This fact has to remain true during the interaction.
When we query 2 and 3, the interactor can make it so that battery 2 is the non-working battery (and so 2 and 3 don't turn the flashlight on). Notice that this is consistent with the information provided by the first query.
Finally, when we query 3 and 4, the interactor is going to reply that those 2 batteries turn the flashlight on. The reason the non-working battery can't be moved to one of those positions is that it wouldn't be consistent with the first two queries, so those two batteries definitely work.
I hope it's clearer now.
Yes got it now, thanks!
So technically The interactor is adaptive has no role here for us (except it guarantees we receive worse case scenario from interactor each time) as there exists a configuration of a working batteries that is consistent with the information that you have received so far.
It's a really cool interactive problem in recent times :)
No. If $$$d \gt 1$$$ and you followed the solution algo up to this point, you must have queried $$$(i, i+d-1)$$$ before. If $$$i+d$$$ was the only broken battery you already found a solution and wouldn't make this query anyway.
If it helps, look at the hangman cheating strategy described in this video by jan Misali. From the player POV there was a some chosen word at the start. From the executioner POV though, they can swap the word at any time to be consistent with information they already gave and the player never knows the difference.
The reason the interactor does this is to force you to have a worst-case solution. You'd expect random guesses to find a pair really quickly, so the interactor needs to simulate you being extremly unlucky while not cheating by contradicting some previous guess.
You can also use the grundy number logic to solve E. First for n > 1
Every cell in col 1 has grundy value 0
Every cell in col 2 has grundy value 1
Every cell in col 3 has grundy value 2
Every cell in col 4 has grundy value 4
...
Every cell in col m has grundy value 2^(m-2)
Now xoring 2^i and 2^j for different i,j would never give 0 So the game state will be 0 if and only if every col (except the 1st one) has even number of tokens. And in that case 2nd player will win.Otherwise, 1st player is the winner.
For n == 1 The grundy value for
Col 1 is 0
Col 2 is 1
Col 3 is 0
Col 4 is 0
...
Col m is 0
So we only need to check if the number of tokens in the col 2 is even or odd.
How are we actually calculating the Grundy Value for Col2 as 1, Col3 as 2, Can you please explain once? Please do share any reference if possible
Col 1 is losing state because you cant move anymore so the grundy is 0
From col 2 you can only do 1 move that is to go to Col 1 so the grundy is MEX(grundy(col 1)) = 1
From col 3 you can go to odd/even number of cell in Col 2 so you can go to both grundy = 0 state (even col2) or grundy = 1 state , So the grundy is MEX(0,1) = 2
From col 4 you can go to odd/even number of cell in Col 3 then odd/even number of cell in Col 2 then col1 so you can go to every state with grundy 0 to 3 thus grundy = mex(0,1,2,3) = 1
generalising this
from Col i you can goto odd/even number of cell in Col (i — 1) then odd/even number of cell in Col (i — 2), .... then go to cell Col 1
Thus you can reach any state with grundy (2^ (i — 3) or 0) + (2^ (i — 4) or 0) + ... (1 or 0) = every state from grundy 0 to (2 ^ (i — 2) — 1)
So the grundy is mex (0 to (2 ^ (i — 2) — 1)) = 2 ^ (i — 2)
This was quite interesting. Thanks for sharing!
I really liked problem E very much
Can anyone help me understand why my code fails the last sample test case for problem C? Thanks!
I assume you've read the editorial and that your code is an implementation of the explanation.
Note that at the very end it says that you should check your constructed solutions. The reason why they might not be valid is that we aren't accounting for the information given by the first value in Harry's list. For both the constructions and the list given in the input, the differences between consecutive values will match, but this doesn't guarantee that their entries are equal.
In the last sample test case, your code constructs a cape arrangement that produces the following list (if we simulate Harry's procedure): "2 1 1". This, of course, doesn't match the input "3 2 2", but notice that $$$2-1 = 3-2$$$ and that $$$1-1 = 2-2$$$.
whoops, I didnt even realize I forgot that, thx
same
I think the tests of problem E may be a bit weak. See my submission 342673253
When $$$n = 1$$$, I simply simulate the process from the maximum column that contains tokens to column $$$1$$$ while updating tokens being held(not in column $$$1$$$) using
std::map. See the code below:The time complexity of the process turns out to be $$$O(m\log m)$$$. After getting Accepted, I soon realized that the sum of $$$m$$$ is not guaranteed and it should get TLE. The last test seems to be $$$n = 1, m = 2\cdot10^5, k = 1$$$ and the only token is $$$(1, 1)$$$ for $$$t = 10^4$$$ testcases.
Can anyone tell me, if the tests are too weak or my code actually has the correct time complexity?
I'm also a bit confused about how that code passes all tests... The process seems completely wrong, but it passes. In fact, the correct way to check if Mimo will win the game when $$$n = 1$$$ is to check whether
mp[2]is odd. This conclusion has been mentioned here,Hello team,
I received a plagiarism warning for problem 2155C (submission: 342105783). I want to clarify that I solved the problem independently and did not share my code or copy from anyone else. If needed, I am happy to explain my detailed thought process and how my solution came about, and the solution i did on paper, because that is how I came up with the approach.
I fully understand the rules and will ensure even stricter isolation in future contests. Please review my case again; I assure you there was no intention of rule violation.
— Codishhh
Hello team, Recently, I got a warning for problem B. I solved it completely on my own and can explain my approach if needed. I think this happened because of a similar approach or code structure. From next time, I will make sure to write code with a different template to avoid such coincidences.
problem D is the worst problem i have ever seen. whoever made this problem never make problems ever again, pls. this is the dumbest shit i've ever seen in my 18 years of life. please find me one honest contestant who figured out the circle circumference bs and didn't just do a simple for loop in for loop without having a clue why it works lol.
maybe solve C before crashing out over D lol. Also here ya go
maybe consider that i didnt have the time to solve C and that D is still a dumb ass question. lmao the guy didn't even specify that he specifically noticed the circumference insight, and the question was specifically formulated to be done with that approach because hacking was not allowed (which in the exact same thread is proven to be possible) therefore making it a worthless algorithm for even the exact question given, hmm i wonder why? maybe because it's a dumb as fuck question that cannot be solved within the constraints and can be hacked whatever approach you choose? but i must be in the wrong, a higher rank has attacked. i will back down now in despair because we reside in a class society.
The comment says "array is cyclic" which means the same thing as "elements are on the circumference of a circle". Quering pairs by distance on a cyclic array would pass the constraints even with better testcases. Yea weak tests suck but all they need to do is have $$$n \lt 25$$$ and non-cyclic solutions become correct
btw I'm not replying after this I don't want to get stuck in a yt comment war
i hope mossad is paying you well to be retarded
he literally did a O(n^2) check and crossed his fingers this guy i cant
There is one more way to look at Problem E.
For n = 1, the number of operations is fixed, so we just need to check the parity of the total sum.
Otherwise:
1 → If a player selects a token from position (r, c), then he/she can either change or keep the same parity of the number of tokens in columns (
1 to c - 1). However, the parity of the current column (c) will always get inverted (from even to odd or odd to even).Since n > 2, it means the player can always make two moves in a column. To change the parity of a column, the player will pick only one row. To keep the parity the same, the player will choose two rows in that column.
2 → Now consider the case where all columns have an even number of tokens. Then, Player 1 makes a move by selecting a token from column c, which may change the parity of some previous columns
(c₁, c₂, c₃, …, cₖ) where cₖ < c.Next, Player 2 chooses a token from the same column c. After this move, the number of tokens in that column becomes even again, and the parity of all the previously changed columns (by Player 1’s move) will also be restored.
Thus, after every two moves (one by each player), all columns will have even parity again. Hence, Player 2 will always have a counter-move for Player 1, and Player 2 will always win in this case.
3 → Now consider the case where at least one column has an odd number of tokens. Let these columns be
(c₁, c₂, …, cₖ) where c₁ < c₂ < … < cₖ < m.In the first move, Player 1 will choose the last column having an odd number of tokens (cₖ). This move will make the parity of column cₖ even and will also flip the parity of all previous columns that had an odd number of tokens.
In this way, Player 1 makes all columns have an even number of tokens. From point (2), we know that in such a situation, Player 2 is in a losing position. Therefore, Player 1 will always win in this case.
didn't participate in contest but interesting problems. a nice way to do O(k) implementation for problem E is to replace the set in the solution with a single integer variable which keeps track of the number of columns with odd tokens.
Problem D has another solution by Divide and conquer:https://mirror.codeforces.com/contest/2155/submission/343548658
Problem $$$D$$$ is a perfect example where the nested loop positioning of outer vs. inner loops makes a real difference.
If the outer loop is on the batteries, we may exhaust the search limit before finding the target pair. On the other hand, having the outer loop for the distance ensures that we find the target once the distance reaches $$$\lfloor{\frac{n}{a}}\rfloor$$$ even though we do not know $$$a$$$.
Nice problem.
Clean af implementation for C!!!
If anyone can answer in problem E 1 13 1 1 4
why is Yuyu winning ?
Problem E could've been one of my all-time favourite, if not for the case $$$n=1$$$. I got stuck for 15 minutes trying to count like an idiot lmao.
I think the 4th possibility in the editorial of C is stated wrong. it should be that i has cape to right and i+1 has cape to left ig
Problem F is a special case of 506D - Mr. Kitayuta's Colorful Graph. I wanted to point out that F is solvable by a fast enough 506D implementation, not just "being simmilar to 506D".