Thank you for participating in the round!
Try to find an invariant
Consider the sum of all elements in the array
It's easy to see that $$$\left( \sum\limits_{i = 1}^n a_i \right) \bmod 4$$$ does not change after a single operation. Therefore, if $$$\left( \sum\limits_{i = 1}^n a_i \right) \bmod 4 \neq 0$$$, then the answer is "NO".
Otherwise, let's make $$$a_1 = 1, a_2 = -1, a_3 = 1, \dots, a_{n - 1} = (-1)^n$$$. We can always do that by performing operations with indices $$$1, 2, 3, \dots n - 1$$$ in this order, and after operation number $$$i$$$ we set the $$$i$$$-th element to the value we want. After that, $$$| \sum\limits_{i = 1}^n a_i | \leq 2$$$, so it is equal to zero because it's the only number divisible by $$$4$$$ in that range.
#include <iostream>
using namespace std;
void solve() {
int n; cin >> n;
int sm = 0;
for (int i = 0; i < n; i++) {
int x; cin >> x;
sm += x;
}
cout << (abs(sm) % 4 == 0 ? "YES\n" : "NO\n");
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
2247B - Yet Another Constructive
When is the answer "NO"?
The answer is "NO" when $$$k \gt m$$$
If $$$m \lt k$$$, then the answer is $$$-1$$$ because it is well known that in any array with $$$m$$$ elements there is a subarray with sum divisible by $$$m$$$. Here is a proof: Consider remainders of prefix sums by $$$m$$$. There are $$$m + 1$$$ prefix sums, and only $$$m$$$ possible remainders by modulo $$$m$$$, therefore two of the prefix sums have the same remainder and in the segment between these two prefix sums the sum is divisible by $$$m$$$.
Otherwise, the solution is to make $$$a_j = 1$$$ for all $$$j$$$ such that $$$j \mod k \neq 0$$$, and $$$a_j = m - k + 1$$$ for $$$j \mod k \equiv 0$$$. In this construction, every subarray of length $$$k$$$ has the sum of exactly $$$m$$$, and every subarray whose length is less than $$$k$$$ obviously has a sum that is greater than $$$0$$$ and less than $$$m$$$, therefore it can't be divisible by $$$m$$$.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n, k, m;
cin >> n >> k >> m;
if (k > m) {
cout << "NO\n";
continue;
}
cout << "YES\n";
for (int i = 0; i < n; i++) {
cout << (i % k == 0 ? m - k + 1 : 1) << ' ';
}
cout << '\n';
}
return 0;
}
2247C - Inversion of a Subsequence
The answer is either $$$-1$$$, or it is $$$\leq 2$$$
If $$$a = b$$$, the answer is $$$0$$$. If $$$a$$$ contains no $$$1$$$-s in it, the answer is $$$-1$$$ because we can't make any operation. Also, if $$$b$$$ doesn't have any $$$0$$$ values, then we can't get $$$b$$$ from any array in one operation, because all values on changed positions should be $$$0$$$ before the operation, but their sum would be even in this case.
If neither of these conditions holds, the answer is always $$$1$$$ or $$$2$$$. It's easy to check whether the answer is $$$1$$$: just consider the positions where $$$a_j \neq b_j$$$, and check if we can do an operation with exactly this set of indices. Otherwise, the answer is $$$2$$$.
Here is a proof: if in the set of indices where $$$a_j \neq b_j$$$ there are $$$\geq 2$$$ indices where $$$a_j = 1$$$, we can just split these wrong indices into two sets with odd sums of $$$a_j$$$. Otherwise, all values that should be changed in array $$$a$$$ are $$$0$$$. Also, there are indices $$$i$$$ and $$$k$$$ such that $$$a_i = b_i = 0$$$ and $$$a_k = b_k = 1$$$ just because the answer is not $$$-1$$$. So let's make the first operation with a subsequence which includes all wrong indices (where $$$a_j \neq b_j$$$) and indices $$$i$$$ and $$$k$$$. The operation is possible because the sum of all $$$a$$$ values is $$$1$$$. After this operation, we can make an operation with only two elements, $$$i$$$ and $$$k$$$. After these two operations, $$$a = b$$$.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> a(n), b(n);
for (int &x : a) cin >> x;
for (int &x : b) cin >> x;
if (a == b) {
cout << 0 << '\n';
continue;
}
int sum = 0;
for (int i = 0; i < n; ++i) {
if (a[i] != b[i]) {
sum += a[i];
}
}
if (accumulate(a.begin(), a.end(), 0) == 0 || accumulate(b.begin(), b.end(), 0) == n) {
cout << -1 << "\n";
continue;
}
if (sum % 2 == 1) {
cout << 1 << '\n';
} else {
cout << 2 << '\n';
}
}
return 0;
}
2247D1 - XOR Sorting (Easy Version)
Imagine you only need to swap elements on some positions $$$i$$$ and $$$j$$$. What is the minimum $$$k$$$ such that you can do it with all XORs of indices $$$\leq k$$$
The answer is always zero or a power of two.
It is inefficient to perform swaps whose index XOR is not a power of two.
Suppose we want to swap $$$a_i$$$ and $$$a_j$$$ $$$(i \lt j)$$$, and $$$i \oplus j$$$ is not a power of two. Let $$$b$$$ be the highest differing bit in numbers $$$i$$$ and $$$j$$$. Then perform the following swaps in order: $$$(i, i + 2^b), (i + 2^b, j), (i, i + 2^b)$$$. It's easy to see that $$$i \oplus (i + 2^b) = 2^b$$$, however, $$$(i + 2^b) \oplus j$$$ might not be a power of two. In this case, we want to replace this swap recursively with the same procedure with a sequence of swaps, such that each of which has an XOR equal to a power of $$$2$$$. It's easy to see that after performing these swaps, the only change in the array is that elements on positions $$$i$$$ and $$$j$$$ are swapped.
Now we want to solve the problem. How do we check whether we can sort the array using only operations with XOR at most $$$2^j$$$? Let's split the array into contiguous blocks of elements with size $$$2^{j + 1}$$$ (the size of the last block may be less than $$$2^{j+1}$$$). It's easy to see that each element will remain in its original block after any number of swaps with XOR $$$\leq 2^j$$$. And within a single block, we can obtain any permutation of its elements just because we can always do any swap inside the block with some sequence of swaps $$$\leq 2^j$$$. Therefore, we only need to check whether sorting every contiguous block of $$$2^{j + 1}$$$ elements, the array becomes sorted.
We can simplify that by only considering two values, $$$min_j$$$ and $$$max_j$$$, which correspond to the maximum and minimum elements in block $$$j$$$. Then we want to check that $$$ \forall j \; | \; max_j \leq min_{j + 1}$$$ holds.
For the simple version of this task, we can check it naively in $$$O(n \log n)$$$ because there are $$$O(log n)$$$ different possible answers, and each one of them can be checked in $$$O(n)$$$.
#include <bits/stdc++.h>
#include <cassert>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n, q; cin >> n >> q;
vector<int> a(n);
for (auto &u : a) cin >> u;
if (is_sorted(all(a))) {
cout << "0\n";
return;
}
for (int x = 0;; x++) {
int mx = -1;
bool good = 1;
for (int j = 0; j * (1 << (x+1)) < n; j++) {
int cmx = -1;
for (int i = 0; j * (1<<(x+1)) + i < n && i < (1<<(x+1)); i++) {
int cur = a[j *(1<<(x+1)) + i];
good &= (mx <= cur);
cmx = max(cmx, cur);
}
mx = max(mx, cmx);
}
if (good) {
cout << (1<<x) << '\n';
return;
}
}
}
signed main() {
cin.tie(0)->sync_with_stdio(false);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
2247D2 - XOR Sorting (Hard Version)
There are a lot of powers of two mentioned in the solution. Which data structure is usually built on an array of a size of a power of two?
Use the segment tree.
First, read the solution for the problem D1.
In the hard version, we need to also handle queries. Let us append several $$$\infty$$$ values to the end of the array so that its length becomes a power of two. Then let's build a segment tree over this array. Now each node of the segment tree corresponds to a block. In each vertex of segment tree we want to maintain the following three values: -maximum value on the segment -minimum value on the segment -minimum $$$k$$$ needed to sort the segment
It is easy to compute the values of a node from the values of its children: maximum and minimum are trivial, and for $$$k$$$ we need to take maximum among our two children, and if $$$max_L \gt min_R$$$ we need to increase $$$k$$$ to length of the segment divided by two. ($$$max_L$$$ is the maximum in the left son, and $$$min_R$$$ is the minimum in the right son).
This solution works in $$$O(n + q \log n)$$$ time.
#include <bits/stdc++.h>
#include <cassert>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n, q; cin >> n >> q;
vector<int> a(n);
for (auto &u : a) cin >> u;
int N = 1;
while (N < n) N *= 2;
while (n < N) {
a.pb(1e9);
n++;
}
vector<array<int, 3>> t(2 * n);
vector<int> L(2 * n, 1);
for (int j = 0; j < n; j++) t[n + j] = {a[j], a[j], 0};
auto pull= [&](int j, int len) {
t[j][0] = min(t[j << 1][0], t[j << 1 | 1][0]);
t[j][1] = max(t[j << 1][1], t[j << 1 | 1][1]);
t[j][2] = max(t[j<<1][2], t[j<<1|1][2]);
if (t[j<<1][1] > t[j<<1|1][0]) t[j][2] = max(t[j][2], len / 2);
};
for (int j = n - 1; j >= 1; j--) {
L[j] = 2 * L[j << 1];
pull(j, L[j]);
}
cout << t[1][2] << '\n';
while (q--) {
int p, x; cin >> p >> x;
p += n;
t[p] = {x, x, 0};
p >>= 1;
int len = 2;
while (p) {
pull(p, len);
p >>= 1;
len *= 2;
}
cout << t[1][2] << '\n';
}
}
signed main() {
cin.tie(0)->sync_with_stdio(false);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
$$$k$$$ should be even in order to have an answer
Try to find lower and upper bounds for $$$k$$$ to have an answer. Every even $$$k$$$ in this range is achievable.
Consider a centroid.
Thanks to Um_nik for sharing this solution! My initial approach was more complicated.
Consider the centroid of the answer and set it as the root of the tree. Then the sum of distances $$$\leq 2 \cdot$$$ (sum of heights of all vertices). It is easy to see that, to maximize the sum of distances, we need to make two roughly equal subtrees with sizes close to $$$\lfloor \frac{n}{2} \rfloor$$$, so we now have an upper bound for our answer. The lower bound is obviously $$$2 \cdot (n - 1)$$$ because we need to traverse each edge at least twice, because we start at vertex 1 and finish there. From this observation, we can also notice that the answer is always even because, for each edge, we must cross from one side of the edge to the other an even number of times to always come back.
Now our goal is to build the tree such that after rooting it with its centroid, $$$2 \cdot$$$ (sum of heights of vertices) equals the required $$$x$$$. Let's start from a tree where the centroid has $$$n - 1$$$ direct children. Then we reroot the children one by one until the sum of heights reaches the desired $$$\frac{x}{2}$$$. We will also maintain the condition that each subtree's size doesn not exceed the $$$\lfloor \frac{n}{2} \rfloor$$$ bound. It is always possible to build such a tree because we know that our answer lies in the range of all possible answers, and we can reroot each vertex not only to the highest vertex from a big subtree, but also to all of its parents, so we can make an increase in the sum of heights by 1, 2, and all numbers up to the current maximum height.
When we have built our tree, we need to label its vertices to solve the problem. Basically, we need to label vertices in such a way that $$$\operatorname{dist}(i, (i \bmod n) + 1) = h_i + h_{(i \bmod n) + 1}$$$, where $$$h$$$ corresponds to the array of all vertices' heights. For this to hold, we need to distribute labels so that vertices $$$i$$$ and $$$(i \bmod n) + 1$$$ end up in different subtrees of the centroid (we will label the centroid as vertex 1 and forget about it because for the centroid the condition holds automatically).
Now it's a standard problem to put each label into some subtree so that two consecutive labels end up in different subtrees. The approach is to assign labels one by one, and we always try to put the label into the subtree with the maximum number of remaining free spots, also considering the last label's subtree. It's easy to prove by induction that, with the constraint on the size of each subtree, this approach works.
This can be implemented in $$$O(n \log n)$$$ time; however, there are many different possible solutions working in linear time. Also, this problem can be solved under the condition that the tree must be a chain, but I prefer the centroid-based solution.
#include <bits/stdc++.h>
#include <cassert>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
void solve() {
ll n, k; cin >> n >> k;
ll top = 0;
for (int x = 1; x <= n / 2; x++) {
top += x;
if (2 * x <= n - 1) top += x;
}
top *= 2;
if (k % 2 == 1 || k < 2 * (n - 1) || k > top) {
cout << "-1\n";
return;
}
if (n == 2) {
cout << "1 2\n";
return;
}
vector<int> cnt(2, (n - 1) / 2);
if (n % 2 == 0) cnt[1]++;
ll cur = top;
cur /= 2;
k /= 2;
for (int i = 0; ; i++) {
int id = i % 2;
if (cnt[id] > 1 && cur - (cnt[id] - 1) >= k) {
cur -= (cnt[id] - 1);
cnt.pb(1);
cnt[id]--;
} else if (cnt[id] > 1 || cur == k) {
vector<pair<int, int>> edges;
int cr = 2;
vector<int> startv(sz(cnt));
for (int j = 0; j < sz(cnt); j++) {
startv[j] = cr;
if (j != id) {
int prv = 1;
for (int x = 0; x < cnt[j]; x++) {
edges.pb({prv, cr++});
prv = cr - 1;
}
} else {
int prv = 1, start = cr;
for (int x = 0; x < cnt[j] - 1; x++) {
edges.pb({prv, cr++});
prv = cr - 1;
}
int was = cnt[j];
int neww = was - (cur - k);
if (neww == 1) edges.pb({1, cr++});
else edges.pb({start + (neww - 2), cr++});
}
}
set<pair<int, int>> st;
for (int j = 0; j < sz(cnt); j++) st.insert({cnt[j], j});
vector<int> per(n + 1);
per[1] = 1;
int lst = -1;
for (int x = 2; x <= n; x++) {
auto it = --st.end();
while ((*it).second == lst) it--;
auto [c,id] = *it;
st.erase(it);
per[startv[id]] = x;
startv[id]++;
lst = id;
assert(cnt[id] > 0);
cnt[id]--;
st.insert({cnt[id], id});
}
for (auto &[u, v] : edges) {
u = per[u]; v = per[v];
cout << u << ' ' << v << '\n';
}
break;
}
}
}
signed main() {
int t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}
Suppose we have two cells in a set. What condition must these two cells satisfy for the set to remain \textit{good}?
These two cells should have the same set of paths going through them. How can we specify \textit{good} sets then?
Consider the rightmost path going from $$$(1, 1)$$$ to $$$(i, j)$$$ and the leftmost path going from $$$(1, 1)$$$ to $$$(i, j)$$$. Find an intersection of these two paths.
First, let us observe that if there is at least one cell in a $$$\textit{good}$$$ set of cells through which no path from cell $$$(1, 1)$$$ to cell $$$(n, m)$$$ passes, then the same is true for all other cells in the set as well. Otherwise, there would exist at least one path contradicting the definition of a $$$\textit{good}$$$ set. Therefore, we can immediately add $$$2^{\text{free}} - 1$$$ to the answer, where $$$free$$$ is the number of free cells through which none of the required paths pass.
From now on, we consider only those free cells through which at least one required path passes. Suppose our set contains some free cell $$$(i, j)$$$ and another cell $$$(i_1, j_1)$$$. Notice that one of the following two conditions must hold: $$$(i_1 \leq i, j_1 \leq j)$$$ or $$$(i_1 \geq i, j_1 \geq j)$$$. This is because at least one required path passes through each of these cells, and if neither condition holds, then such paths cannot coincide, since a path may only move either one cell down or one cell to the right;
In the first case, $$$(i_1 \leq i, j_1 \leq j)$$$, we need the following condition: every path from $$$(1, 1)$$$ to $$$(i, j)$$$ must pass through cell $$$(i_1, j_1)$$$; otherwise, the set is not $$$\textit{good}$$$. Similarly, if the second condition $$$(i_1 \geq i, j_1 \geq j)$$$ holds, then every path from cell $$$(i, j)$$$ to $$$(n, m)$$$ must pass through cell $$$(i_1, j_1)$$$.
Therefore, we construct directed edges from cell $$$(i, j)$$$ to all cells $$$(i_1, j_1)$$$ such that $$$(i_1 \leq i, j_1 \leq j)$$$ and every path from $$$(1, 1)$$$ to $$$(i, j)$$$ passes through $$$(i_1, j_1)$$$, and also to all cells satisfying $$$(i_1 \geq i, j_1 \geq j)$$$ such that every path from $$$(i, j)$$$ to $$$(n, m)$$$ passes through $$$(i_1, j_1)$$$. Then we find the strongly connected components of this graph. A set of cells is good if and only if all of its cells belong to the same SCC.
Essentially, such edges mean that every path from $$$(1, 1)$$$ to $$$(n, m)$$$ passing through $$$(i, j)$$$ also passes through $$$(i_1, j_1)$$$. This makes it clear that if all cells of the set belong to one SCC, then the set is good; otherwise, it is not.
Now let us understand how to efficiently find SCCs in this graph. Consider only the edges from cells $$$(i, j)$$$ to cells $$$(i_1, j_1)$$$ satisfying $$$(i_1 \leq i, j_1 \leq j)$$$. Notice that if there exists an edge $$$(i, j) \rightarrow (i_1, j_1)$$$ and an edge $$$(i_1, j_1) \rightarrow (i_2, j_2)$$$, then there also exists an edge $$$(i, j) \rightarrow (i_2, j_2)$$$, because the edge $$$(i, j) \rightarrow (i_1, j_1)$$$ means that all paths from $$$(1, 1)$$$ to cell $$$(i, j)$$$ pass through cell $$$(i_1, j_1)$$$.
We can also observe that all cells reachable by such edges from $$$(i, j)$$$ form a path in the directed graph. Therefore, for each cell $$$(i, j)$$$ it is sufficient to find the edge to the cell $$$(i_1, j_1)$$$ with the maximum value of $$$i_1 + j_1$$$.
We process cells in increasing order of $$$i + j$$$. If cell $$$(i - 1, j)$$$ is reachable from $$$(1, 1)$$$ and cell $$$(i, j - 1)$$$ is not reachable from $$$(1, 1)$$$, then the required edge goes to cell $$$(i - 1, j)$$$. Similarly, if cell $$$(i - 1, j)$$$ is not reachable from $$$(1, 1)$$$ and cell $$$(i, j - 1)$$$ is reachable from $$$(1, 1)$$$, then the required edge goes to cell $$$(i, j - 1)$$$.
Otherwise, the required edge goes to the LCA of cells $$$(i - 1, j)$$$ and $$$(i, j - 1)$$$ in the tree formed by the previously constructed SCC edges.
Analogously, we can construct edges $$$(i, j) \rightarrow (i_1, j_1)$$$ to cells satisfying $$$i_1 \geq i$$$ and $$$j_1 \geq j$$$.
Thus, our graph contains only $$$O(nm)$$$ edges, and we can easily find its SCCs.
To answer LCA queries in the tree, we use binary lifting. Therefore, the overall complexity of the solution is $$$O(nm \log nm)$$$ time and $$$O(nm \log nm)$$$ memory.
In fact, building SCCs is not even necessary. We can merge two cells $$$A$$$ and $$$B$$$ in dsu if $$$A$$$ is the direct parent of $$$B$$$ in a tree built from the cell $$$(1, 1)$$$ and if $$$B$$$ is the direct parent of $$$A$$$ in a tree built from the cell $$$(n, m)$$$.
#include <bits/stdc++.h>
#include <cassert>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
const int maxl = 20, maxn = 1e6 + 10;
int up[maxl][maxn];
constexpr ll mod = 998244353;
ll sum(ll x, ll y) {
return (x + y >= mod ? x + y - mod : x + y);
}
ll mul(ll x, ll y) {
return (x * y) % mod;
}
ll diff(ll x, ll y) {
return (x >= y ? x - y : x + mod - y);
}
void solve() {
int n, m; cin >> n >> m;
vector<string> s(n);
for (auto &u : s) cin >> u;
vector<vector<int>> is_path(n, vector<int>(m));
vector<int> h(n * m);
vector<vector<int>> g_scc(n * m);
for (int j = 0; j < maxl; j++) up[j][0] = 0;
auto newv = [&](int v, int p) {
g_scc[v].pb(p);
h[v] = h[p] + 1;
up[0][v] = p;
for (int j = 1; j < maxl; j++) up[j][v] = up[j - 1][up[j - 1][v]];
};
auto jump = [&](int v, int where) {
for (int j = maxl - 1; j >= 0; j--) {
if (((h[v] - where) >> j) & 1) v = up[j][v];
}
return v;
};
auto lca = [&](int u, int v){
if (h[u] > h[v]) swap(u, v);
v = jump(v, h[u]);
if (u == v) return u;
for (int j = maxl - 1; j >= 0; j--) {
if (up[j][v] != up[j][u]) {
v = up[j][v]; u = up[j][u];
}
}
return up[0][v];
};
is_path[0][0] = (s[0][0] == '1');
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (i == 0 && j == 0) continue;
if (s[i][j] == '0') continue;
is_path[i][j] = (i > 0 && is_path[i - 1][j]) || (j > 0 && is_path[i][j - 1]);
if (is_path[i][j]) {
int par;
if (i == 0 || !is_path[i - 1][j]) par = i * m + j - 1;
else if (j == 0 || !is_path[i][j - 1]) par = (i - 1) * m + j;
else par = lca((i - 1) * m + j, i * m + j - 1);
newv(i * m + j, par);
}
}
}
h.assign(n * m, 0);
for (int j =0; j < maxl; j++) up[j][n * m - 1] = n * m - 1;
vector<vector<int>> is_path2(n, vector<int>(m));
is_path2[n - 1][m - 1] = (s[n - 1][m - 1] == '1');
for (int i = n - 1; i >= 0; i--) {
for (int j = m - 1; j >= 0; j--) {
if (i == n - 1 && j == m - 1) continue;
if (s[i][j] == '0') continue;
is_path2[i][j] = (i + 1 < n && is_path2[i + 1][j]) || (j + 1 < m && is_path2[i][j + 1]);
if (is_path2[i][j]) {
int par;
if (i + 1 == n || !is_path2[i + 1][j]) par = i * m + j + 1;
else if (j + 1 == m || !is_path2[i][j + 1]) par = (i + 1) * m + j;
else par = lca((i + 1) * m + j, i * m + j + 1);
newv(i * m + j, par);
}
}
}
int cntbad = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) cntbad += (!is_path[i][j] || !is_path2[i][j]);
}
ll ans = 1;
for (int j = 0; j < cntbad; j++) ans = mul(ans, 2);
ans = diff(ans, 1);
// cout << cntbad << endl;
vector<int> used(n * m), ord;
auto dfs = [&](int v, auto&&self) -> void {
used[v] = 1;
for (int u : g_scc[v]) if (!used[u]) self(u, self);
ord.pb(v);
};
for (int j =0; j < n * m; j++) {
if (!used[j] && is_path[j/m][j % m] && is_path2[j/m][j % m]) dfs(j, dfs);
}
reverse(all(ord));
vector<bool> is_good(n * m);
for (int el : ord) is_good[el] = 1;
vector<vector<int>> grev(n * m);
for (int i = 0; i < n * m; i++) for (int u : g_scc[i]) grev[u].pb(i);
vector<int> cnt;
used.assign(n * m, 0);
auto dfs2 = [&](int v, auto&&self) -> void {
cnt.back()++;
used[v] = 1;
for (int u : grev[v]) {
if (!used[u] && is_good[u]) self(u, self);
}
};
for (int u : ord) {
if (!used[u]) {
cnt.pb(0);
dfs2(u, dfs2);
}
}
for (int c : cnt) {
ll cur = 1;
for (int j = 0; j < c; j++) cur = mul(cur, 2);
ans = sum(ans, diff(cur, 1));
}
cout << ans << '\n';
}
signed main() {
int t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}








How do we solve E to have a chain based solution?I tried this in the contest but i couldn't find a solution.
It's a similar sort of solution IMO, at least the way I did it. The answer can take the form of a central chain with some number of additional leaves hanging off, centered at 1. You can show that the maximum possible answer is generated from a chain that starts at 1 and alternately adds on the left and right sides. Note that this puts the evens one one side and the odds on the other, so each path always includes the center. You can take the step of moving a leaf toward the center incrementally, which decreases the sum by two, until the minimal possible answer of a star. Binary search to find an initial structure above but close to the desired k, whose sum is easy to calculate (there are multiple families that can be chosen here)
Hi, "You can show that the maximum possible answer is generated from a chain that starts at 1 and alternately adds on the left and right sides" How did you show that this indeed is the max possible answer over all possible trees? I have a proof for but its quite complicated, do you have a simple one?
Consider a maximal-distance tree, and consider some maximal path on that tree. If the path has a spur, say it has $$$x$$$ times the neighbor-cycle entering/exiting the spur goes left and $$$y$$$ times it goes right (with some number possibly going across). Then if $$$x\ge y$$$ reattach the spur on the right end otherwise reattach it on the left end; this will increase or maintain the total distance. This decreases the number of leaves by one; repeat until no spurs remain; this shows some chain is maximal. To see that my labeling scheme is optimal, consider that each edge on the chain is crossed at most $$$2*\text{min}(\text{left_size},\text{right_size})$$$ times, which is reached by my labeling.
A chain-shaped tree of the form $$$1, 2, ..., n$$$ has sum $$$2(n - 1)$$$. This is the minimal sum which can be achieved; any additional sum requires rearranging the nodes. Let the remaining sum be $$$r = k - 2(n - 1)$$$. For starters, if $$$r \lt 0$$$, no valid arrangement exists.
Try reversing two adjacent nodes in this chain. You'll notice that adjacent swaps involving the end elements ($$$1$$$ and $$$2$$$, or $$$n - 1$$$ and $$$n$$$) don't change the sum, whereas any other adjacent swap adds 2 to the sum. This is because any adjacent swap adds 2 to the number of times the edge between the nodes is crossed. In fact, the sum of distances for any tree is always even, as every edge must be crossed an even number of times. So if $$$r$$$ is odd, no valid arrangement exists either.
If you try reversing longer contiguous subsequences of nodes, you'll notice that the amount added to the sum is equal to $$$2$$$ times the number of edges involved ($$$2(m - 1)$$$ for a contiguous subsequence of $$$m$$$ nodes). $$$m$$$ can be at most $$$n - 2$$$, because, as previously mentioned, reversing the end elements doesn't help us.
But what if reversing every element between $$$1$$$ and $$$n$$$ isn't enough to reach $$$k$$$? The key insight here is that this is now a recursive problem. We simply repeat the same strategy on the reversed contiguous subsequence from $$$2$$$ to $$$n - 1$$$. Thus, we have turned this graph problem into a recursive array problem.
Implementing said strategy results in an $$$\mathcal O(N)$$$ solution. For those looking for a (slightly messy) reference code, see my submission.
For anyone looking for a more detailed breakdown of Problem E, I wrote a separate tutorial focusing on the math intuition and the step-by-step visual construction of the chain-based solution (splitting evens and odds).
You can read it here: Detailed Explanation
I have a solution that is quite different, but it is a chain.
So we start with the maximum total dist, by putting all odd numbers in order in front of even numbers, like 1 3 5 7 2 4 6 8 for n = 8. We try to move even numbers in front, one by one to reduce total dist, but not beyond the odd number that is smaller than it, as that will increase total dist. For simplicity(and to follow my code logic, I will be dividing dist and contribution by 2)
For even n, swapping a even number 2a to one position to the front in the chain result in -2, -2, -2, ... -1 contribution, giving to total of 2 * (n/2-a)-1.
For odd n, however, the contribution will be -1, -2, -2, -2, ... -1, giving a total of 2 * ((n+1)/2-a)-2. (swapping an even number with the last odd number will only give -1 here). Then we can use buckets to store where even numbers ended up at in the end, or to be more specific, which odd number is it after.
Some more implementation details are in my code. My explanation is not that good so hopefully my code helps. (Somehow my code seem clearer than my explanation)
383352745
Just find the pattern I think. For a chain from 1 to n, we can find moving any single node except 1 and n changes the contribution by 2. So we can move 2 to the end of the chain and then move 4 in order to not affect the change caused by moving 2. And we can move other even nums in the same way. In this way we can increase by 2 each time and construct it very easily.
for E
make edge case for n=2
upperbound is n^2//2 lowerbound is 2n-2 k should be even if not satisfied return -1
make edge 1 2 and 1 3 now we need to place n-3 more edges it can be seen that the min answer can be made by connecting all nodes to 1
now how do we increase the answer? let x be 2*n-2 we increase answer from minimum
make a left branch starting from 2 and a right branch starting from 3 for each i=4 to n if x+2*depth(left branch)<=k then append i to left/right branch according to parity of i-th node else we append i-th branch to depth of p where x+2*p==k
once this condition satisfies append rest of the nodes to 1
code: https://codeforces.me/contest/2247/submission/383475803
For a given edge, if $$$i$$$ is on the left side of that edge and $$$i+1$$$ is on the right side, then that edge’s contribution to the result increases by $$$2$$$.
The minimum result is easy to construct: $$$1$$$~$$$2$$$~$$$3$$$~...~$$$n-1$$$~$$$n$$$
Next, we will consider swapping adjacent numbers along this chain.
First, move $$$n-1$$$ to the very front (note that the edge $$$1$$$–$$$2$$$ cannot further increase the result, so we will not swap $$$n$$$ and $$$n-1$$$); each swap increases the result by $$$2$$$.
After the swap, the order of the chain becomes: $$$1$$$–$$$n-1$$$–$$$2$$$–$$$3$$$–...–$$$n-2$$$–$$$n$$$
Note that the edge $$$1~2$$$ cannot further increase the result, so we do not move $$$n-1$$$ to the far left.
Similarly, we move $$$n-3$$$ to the right of $$$n-1$$$, move $$$n-5$$$ to the right of $$$n-3$$$, and so on until the result can no longer be increased.
This process is easy to implement; for details, see https://codeforces.me/contest/2247/submission/384141836.
Was there any actual reason in D2 the constraints for n and q could go to 1000000? From what it looks like using n,q <= 200000 or 300000 or 500000 would have still ensured only the intended solutions really pass, and all 1000000 did was make the implementation in Python far more gimmicky and inconsistent than it needed to be. Also if there was some sort of weird O(n + q log n log n) type of solution you were trying to prevent with this constraint then I vehemently disagree with this choice as if someone really wanted they could ridiculously optimize their solution to make such a runtime work
Agree
It is likely to kill off O(nlog^2(n)) solutions that didn't merge the per interval update into the segment tree
It also kills O(n log) solutions with set apparently...
https://youtu.be/0PlscpOXFlM
I don’t know, it might’ve been too strict if you ask me
such a fast Thanks
There is an issue in rate the problem
is C solvable if we have to choose a subsegment instead of a subsequence? Because i misread subsequence as subsegment and couldnt solve it till i realized my mistake
same buddy , i read it subsegment
There is a nice hashing solution to F.
For a cell $$$c$$$, we denote $$$P(c)$$$ to be the set of paths that goes from $$$(1,1)$$$ to $$$(n,m)$$$ via $$$c$$$. Then, a set of cells $$$S$$$ is good if and only if for all $$$s \in S$$$, the sets $$$P(s)$$$ are the same.
We want to find a good way to hash the set of paths. To do so, we first assign a random weight to each edge (a downward / rightward move). We then let the hash value of a path from $$$(1,1)$$$ to $$$(n,m)$$$ to be the product of the weights that it passes through. Finally, for any cell $$$s$$$, we define the hash value of $$$P(s)$$$ to be the sum of the hash values of the paths passing through it.
This is convenient for us because the hash value $$$P(s)$$$ can be calculated easily with two DPs: we let $$$dp1[i][j]$$$ be the sum of hash value of all paths going from $$$(1,1)$$$ to $$$(i,j)$$$ only, and similarly $$$dp2[i][j]$$$ be the sum of hash value of all paths from $$$(n,m)$$$ to $$$(i,j)$$$. Then, $$$P((i,j))$$$ is just $$$dp1[i][j] \times dp2[i][j]$$$.
Our output is then obviously $$$\sum_{P(i,j)} 2^{\text{number of occurrences of }P(i,j)}-1$$$.
Submission: 383355741
im surprised this wasn't the intended solution given how clean it is
I'm sure the odds are extraordinarily low, but any idea what the odds of a hash collision are here?
You can further find the dominance relationships corresponding to the path set, thus achieving deterministic $$$\mathcal{O}(nm)$$$, just like my approach below.
You can interpret the hash as a multivariate polynomial in $$$R[x_1,x_2,\dots, x_e]$$$ where the $$$x_i$$$ each correspond to an edge. The degree of the multivariate polynomial $$$P(s)$$$ is at most $$$n+m-2$$$, because down-right paths are of length at most $$$n+m-2$$$.
By using this Schwartz Zippel Lemma you can prove that if you now substitute the $$$x_i$$$ with random values, and calculate the result mod a prime $$$p$$$, the chance that two non-identical path collections evaluate to identical is $$$\leq \frac{n+m-2}{p}$$$. To prove that the probability of a collision between any pair is small enough, we need to repeat this twice with some other independently random weights substituted, to get for example $$$\leq \left(\frac{n+m-2}{p}\right)^3$$$ probability of a single collision. The probability of any collision appearing for a distinct pair is then $$$ \leq 1- (1-(\frac{n+m-2}{p})^3 )^{{nm}\choose{2}}$$$. If you calculate this with some reasonable values for $$$n,m,p$$$ you'll notice that you need quite a number of hashes to get a provably correct algorithm (I am not sure if $$$3$$$ hashes is enough). In practice the collision probability for two $$$P(s)$$$ seems closer to $$$\frac{1}{p}$$$ and $$$3$$$ hashes does pass all the tests.
The one time I recognize a question used segment tree, I wasn't able to do it :(
For problem F, we can indeed directly construct the graph and use the dominator tree to achieve a time complexity of $$$\mathcal{O}(nm \log (nm))$$$. However, due to the D/R operation on the plane, we can actually inductively derive the tightest constraint of the dominance relationship from the original graph, thus achieving a strict $$$\mathcal{O}(nm)$$$ time complexity with more concise logic.
In short, considering backwards, let $$$P(x,y)$$$ represent the set of all valid start-end paths passing through position $$$(x,y)$$$. Then, if $$$S$$$ is valid, it is true if and only if all positions $$$(x,y) \in S$$$ have the same $$$P(x,y)$$$. Therefore, we only need to find these equivalence classes. For a position $$$(x,y)$$$ that lies on at least one complete valid path, relative to the D/R operation, we can define $$$U_{x,y}$$$ and $$$L_{x,y}$$$ as the complete paths passing through the top and leftmost edges of $$$(x,y)$$$, respectively. Then, all paths passing through $$$(x,y)$$$ must be sandwiched between these two paths. Therefore, $$$P(x_1,y_1) = P(x_2,y_2)$$$ is actually equivalent to $$$U_{x_1,y_1} = U_{x_2,y_2}$$$ and $$$L_{x_1,y_1}=L_{x_2,y_2}$$$. We can dynamically transform these two paths into local variables based on how they were generated. For example, when entering a cell on the topmost path, it prioritizes entering from the top; otherwise, it enters from the left. When leaving, it prioritizes going right; otherwise, it goes down. From a topological sorting perspective, we can directly calculate $$$(U,L)$$$ for each position in order. Taking the generation of $$$U_{x,y}$$$ as an example, if the update $$$(i,j) \to (x,y)$$$ is along the priority direction, then $$$U_{i,j}=U_{x,y}$$$; otherwise, $$$U_{x,y}$$$ will have its own larger new id. Then we can directly use this pair as the basis for dividing equivalence classes.
For all positions not traversed by a complete path, they are grouped into a separate equivalence class. For an equivalence class $$$C$$$ of size $$$|C|$$$, the corresponding contribution is $$$2^{|C|} - 1$$$.
Thus, a solution with a deterministic $$$\mathcal{O}(nm)$$$ time and space complexity can be obtained directly using two rounds of counting sort/bucket sort.
my submission
383372267 My solution to D1 is quite simpler compared to the editorial ig. But i couldn't prove it properly it definitely works for distinct elements but i was confused about equal ones.
Thanks! A very nice code you've written
What if the array in Problem Aalso had 0 with 1 and -1 and everything else remain the same is it solvable then? if so how ? I could not think of anything
if -0==0 , then if 0 is present , it would be just sum %2 invariant
No but that zero could affect -1 and 1 to change signs then %4 does not work i have tried that
thas why then its sum mod 2 invariant
E IS AMAZING
My contest discussion stream here for ABCD1D2
I reached Expert in our final Binary Contest!!!
historical.
This contest went very bad for me. I read the question C but while thinking completely misremembered it as consecutive elements, which is much harder problem. It was such an easy problem to solve. So angry at myself.
Another implementation for D1 : link
does this actually work? doesn't look correct to me. if you use stable sort then it can work. that is what i did. also you don't give compare function to sort. how can it know how to sort an array<ll,2>
I wanted to share some intuition for D:
For a fixed $$$k$$$, define $$$p$$$ as the maximal power of $$$2$$$ less than or equal to $$$k$$$.
Beginning at index 0, we can swap with indices in the range $$$[0, p]$$$ as $$$0 \oplus x = x$$$ and the entire range $$$[0, p] \leq k$$$.
Beginning at index $$$p$$$, we can swap with indices in the range $$$[p, 2p - 1]$$$ as $$$p \oplus x = x - p$$$ when $$$x \in [p, 2p - 1]$$$, thus $$$p \oplus x \in [0, p - 1]$$$.
Note that $$$p \oplus 2p = 3p$$$ which would exceed our threshold of $$$k$$$, so we must stop at $$$2p - 1$$$.
Notice the overlap between the regions $$$[0, p]$$$ and $$$[p, 2p - 1]$$$. This gives us the ability to swap across regions, and sort the entire range $$$[0, 2p - 1]$$$.
More generally, for every aligned block $$$[2tp, 2(t+1)p - 1]$$$, the same argument applies because all indices share the same higher bits, so their XOR depends only on their positions within the block. No swap can cross between two such blocks, since indices in different blocks differ in a bit worth at least $$$2p \gt k$$$.
This explanation highlights why the answer should always be a power of $$$2$$$ (or $$$0$$$). The intervals we can sort are solely dependent on $$$p$$$, and $$$p$$$ only changes when $$$k$$$ reaches a power of 2. Thus choosing something like $$$k = 11$$$ is pointless when $$$k = 8$$$ gives you the exact same flexibility to swap.
D1: 383402115
D2: 383410424
Thank you I was able to see the pattern but was not able to understand why this was working. One small correction, in the third line the set should be [0, p-1] instead of [0, p]
edit: sorry my bad I'm dumb didn't read the explaination carefully
That is not a mistake. Consider when $$$k = p = 4$$$, then $$$0 \oplus p = 4$$$ and $$$ 4 \leq k$$$. If your change were correct, there would be no overlap between $$$[0, p - 1]$$$ and $$$[p, 2p - 1]$$$.
I think I also saw an alternate solution in which the answer was the highest power of 2 smaller than or equal to i^sorted(i) where i is the original index and sorted(i) is the index of the a[i] in sorted array. I wonder why this solution works...
That is a nice simplification.
As for why it works:
Consider some $$$i$$$ and $$$j = sorted(i)$$$.
For a fixed power of two $$$p$$$, we need both $$$i$$$ and $$$j$$$ to fall in the same $$$[2tp, 2(t + 1)p - 1]$$$ bucket. Since elements can never leave their connected component, this is precisely the condition required for the element at index $$$i$$$ to reach its destination.
This condition is equivalent to the highest power of $$$2$$$ in $$$i \oplus j$$$ being at most $$$p$$$.
Why? Consider the highest bit of $$$i \oplus j$$$, refer to this as bit $$$b$$$ (i.e. the $$$b$$$'th bit from the right, $$$0$$$-indexed). This is the highest bit where $$$i$$$ and $$$j$$$ differ. It follows that $$$i$$$ and $$$j$$$ are separated when considering groups of size $$$2^b$$$, but connected when considering groups of size $$$2^{b+1}$$$ (since $$$2^b$$$ is the largest group size that keeps them separated).
Therefore, the minimum power of $$$2$$$ required for the element at index $$$i$$$ to reach its sorted position is exactly the highest power of $$$2$$$ contained in $$$i \oplus j$$$. Since every element must be able to reach its destination, the answer is the maximum of this quantity over all pairs $$$(i, sorted(i))$$$.
Oh I think I got it now. Thanks for your commments I appreciate it.
I will add to the intuition of why in the first place pick p, which is highest power of 2 less than or equal to k
think in terms of msb's, suppose you have some element which needs to be moved out of its msb position to some lower msb position(to be sorted), then analyze this situation and see what must be the lower bound of k, you will find out the power of 2.
How do you all develop the thinking? When I was solving question three, I could think that we need sum for mismatches in A. The only answers can be -1,0,1,2. 2 when sum is even cause we can only flip when sum is odd, hence with odd + odd which is even, the max flips we would need is 2. Also that if there is no 1, we can't flip in a so -1 if not same. But how did you think of all ones in B? did it just click or you all tried several cases here and there? And the questions after those, Haha~! I couldn't even understand them.
**An O(N) purely constructive idea for E without LCA and Centroid **
Let's say n = 7.
Minimum sum of distances with a line graph (G1): 1-2-3-4-5-6-7 -> Sum: 12. Formula: 2*n — 2. Maximum sum of distances with a line graph (G2, one possibility): 1-3-5-7-6-4-2 -> Sum: 24.
How to get G2 (Maximum): To maximize dist(1, 2), keep '2' as far as possible from 1. Then for dist(2, 3), keep '3' as far as possible from '2'. From this intuition, you can build G2 to achieve the absolute maximum value.
How to build an intermediate graph for a required k: k must be in between this minimum and maximum value, and it can only increase by increments of +2.
Let's imagine the tree is rooted at '4'. If you swap 2 one position to the right in G1, the sum of the distance values for the new graph will increase by exactly 2 from the minimum value. For every right-side swap, the total distance increments by 2 (except for the final boundary position). Note that the distance sum of 1-3-4-5-6-2-7 and 1-3-4-5-6-7-2 will be the same, but we prefer the swap that brings 7 ahead to maintain array boundaries.
Allowed right-shifts (swaps) for each even number follows the formula (n — i — 1):
For 2, allowed swaps: 4 (since 7 — 2 — 1 = 4) For 4, allowed swaps: 2 For 6, allowed swaps: 0
From fully exhausting these swaps, the maximum distance we can add is (4 + 2) * 2 = 12. Total reach = minimum + 12 = 12 + 12 = 24 (which perfectly matches our maximum).
Take remaining = k — minimum. If you iterate step-by-step for each individual swap, it will result in Time Limit Exceeded (TLE). Instead, do it in O(1) chunks: check if it is possible to exhaust all allowed swaps for 2. If so, decrease remaining and move on to check 4. If only a fraction of the swaps are needed to hit the target k, simply take (remaining / 2) to get the exact required index shift.
These calculated "swaps" denote the number of indices an even value is shifted rightward from its starting configuration in the minimum graph (G1). We place the shifted even values into their final calculated indices, and then fill the empty slots with the remaining unused odd and even numbers in natural order.
The — i Offset: The final position of 4 will need to be shifted one index left from the absolute end because 2 has already been placed at the end. The position of 6 will be shifted two indices left because both 2 and 4 were placed before it. That is exactly why the index placements in the code subtract the iteration counter i:
g[node_num + max_inc + 1 — i] = node_num; g[node_num + c — i] = node_num;
you can see my submission here : 383463345
Simpler implementation for D1:
Time Complexity: $$$O(n \log n)$$$
Space Complexity: $$$O(n)$$$
can anyone explain Question b pls i didn't get the editorial
for example k=5 and m=3:
$$$a = [3, 1, 1, 3, 1, 1,...]$$$
just construct like that
Another construction for E:
Take the form $$$1, n, n-1, n-2 \cdots 2$$$. Initialize $$$t = 0$$$
If $$$t \equiv 0 \operatorname{mod} 2$$$, take $$$(t+ 1)^{th}$$$ element and keep swapping with adjacent elements until there remain $$$t + 1$$$ elements in the suffix(not including the chosen element itself). Then at the end do $$$t$$$++.
If $$$t \equiv 1 \operatorname{mod} 2$$$, skip. $$$t$$$++.
Now the answer can be found by simple binary search.
For every swap, the answer increments by 2 and thus the total number of swaps and the actual possible answers match. While not a mathematical proof, it is mathematical evidence. Off to sleep now...
No way D1 and D2 core bitwise logic strike between timed contest!!! bruhh..
I strongly recommend that make D2's time limit higher,like to make it to 3 seconds.
What about this solution for E
I guess my this solution is much easier to implement:
For D1, my method:
First, stably sort the array (by value, then by original index). For every element whose position changes, compute the XOR of its original index and its new index. The answer is the maximum highest power of two among these XOR values.
It's pretty simple to implement.
I wrote a slightly better time complexity code for problem E Build a Tree
If it wasn't for printing edges my code beats solution code in processing
I request anyone to check if my code gives correct output for entire input space
Approach : Find largest number where this condition hold true
(k >= (m* m) / 2 + 2 * (n — m))
construct largest k for whose m edges : as in b2 (function)method continue this process for k-m(m)/2 and soon until k>remaining_n(remaining_n)/2 logic is provided im below code to handle remaining_n
For D1, a lot of people (including me) seem to have come across the solution of creating a new array $$$b$$$ where $$$b_i = [a_i, i]$$$, sorting it, and taking the maximum value of $$$\operatorname{msb}(i, b_{i_2})$$$. Two things:
1: I haven't seen anyone write a proof for it. While I won't write a full proof, it can be proved with the following two observations:
The maximum MSB of swaps that don't move target elements into place will always be less than or equal to the maximum MSB of swaps that move target elements into place.
If multiple elements are equal, it is optimal to put the element with the maximum original index into the maximum target index.
2: Is this solution extendable into D2?
I feel so confused ,for C, if a=[1,0,1,0],b=[1,1,1,0],why the answer is 2, I can't find the way
assume 0 based indexing : 1st opn : (1,2,3), 2nd opn : (2,3); it will work,,
PvPro why the ans of the test case : a = 1 0 0 b = 1 1 1 is 2 and why not -1 ??
For a = [1,1,1] and b = [0,0,0]:
Choose all three elements. Their sum is 3, which is odd, so the operation is allowed.
Flip them: [1,1,1] → [0,0,0].
So the answer is 1, not -1.