Codeforces Round 1059 (Div. 3) Editorial
Difference between en13 and en14, changed 0 character(s)
A↵

Idea: [user:wakanda-forever,2025-10-10]↵
Preparation: [user:wakanda-forever,2025-10-10]↵

<spoiler summary = "Solution">↵
Let's say we have a sequence of numbers with an average equal to $k$.↵

Adding a number greater than $k$ increases the average, while adding a smaller one decreases it.↵

Therefore, the maximum average subarray is formed by taking the maximum element, since including anything smaller would only lower the average.↵

Hence, the final answer is the maximum element of the given array.↵

Time Complexity: $O(n)$ per testcase.↵
</spoiler>↵

<spoiler summary = "Implementation">↵
~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
 ↵
#define ll long long↵
 ↵
int main(){↵
 ↵
    int t;↵
    cin >> t;↵
 ↵
    while(t--){↵
        int n;↵
        cin >> n;↵
 ↵
        vector<int> a(n);↵
        for(int i = 0; i < n; i++) cin >> a[i];↵
 ↵
        cout << *max_element(a.begin(), a.end()) << endl;↵
    }↵
 ↵
    return 0;↵
}↵

~~~~~↵
</spoiler>↵



B↵

Idea: [user:wakanda-forever,2025-10-10]↵
Preparation: [user:tridipta2806,2025-10-10]↵

<spoiler summary = "Solution">↵
We need to find a non-decreasing subsequence $p$ such that, after removing its characters from the string $s$, the remaining string $x$ becomes a palindrome.↵

Observe that if we choose $p$ to consist of all the $0$'s in $s$, then $x$ will contain only $1$'s, which always forms a palindrome. Similarly, if we take $p$ as all the $1$'s, then $x$ will contain only $0$'s, which is also a palindrome.↵

In both cases, $p$ is clearly a non-decreasing subsequence (since all its elements are equal).↵

Therefore, a valid solution always exists — we can simply output the indices of either all $0$'s or all $1$'s in the string.↵



Time Complexity: $O(n)$ per testcase.↵
</spoiler>↵

<spoiler summary = "Implementation">↵

~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
 ↵
#define ll long long↵
 ↵
int main(){↵
 ↵
    int t;↵
    cin >> t;↵
 ↵
    while(t--){↵
        int n;↵
        cin >> n;↵
 ↵
        string s;↵
        cin >> s;↵

        vector<int> pos;↵
        for(int i = 0; i < n; i++) if(s[i] == '0') pos.push_back(i + 1);↵

        cout << (int)pos.size() << '\n';↵
        for(auto& z : pos) cout << z << ' ';↵

        cout << '\n';↵
    }↵
 ↵
    return 0;↵
}↵

~~~~~↵


</spoiler>↵



C↵

Idea: [user:wakanda-forever,2025-10-10]↵
Preparation: [user:wakanda-forever,2025-10-10]↵

<spoiler summary = "Solution">↵
We are allowed to choose any $x$ such that $0 \le x \le a$ and set $a := a \oplus x$. Our goal is to make $a$ equal to $b$.↵

Let's think of the binary representation of $a$. Consider the highest set bit (most significant bit) of $a$ and let's assume its position is $\operatorname{msb}(a)$.↵

At each operation, we are choosing $x \le a$, which implies that $\operatorname{msb}(x) \le \operatorname{msb}(a)$ (otherwise, we have $x > a$).↵

$$↵
\displaystyle↵
\begin{matrix}↵
a = (00\dots01\dots\dots)_2 \\↵
x = (00\dots0\dots1\dots)_2↵
\end{matrix}↵
$$↵

Now, we can surely say that $\operatorname{msb}(a \oplus x) \le \operatorname{msb}(a)$.↵

Thus, by performing the given operation, $\operatorname{msb}(a)$ will never increase. So, if $\operatorname{msb}(b) > \operatorname{msb}(a)$, the answer is $-1$.↵

Otherwise, we can always transform $a$ into $b$ in a constructive manner.↵

First, we set all bits below $\operatorname{msb}(a)$ one by one to ensure that every required bit can be manipulated. Then, for each bit that is $0$ in $b$, we unset it using an appropriate XOR operation.↵

By following this process, we can reach $b$ from $a$ in less than $60$ operations.↵



Time Complexity: $O(\log_2(a))$ per testcase.↵
</spoiler>↵

<spoiler summary = "Implementation">↵

~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
 ↵
int main(){↵
 ↵
    int t;↵
    cin >> t;↵
 ↵
    while(t--){↵
        int a, b;↵
        cin >> a >> b;↵
        ↵
        if(__builtin_clz(a) > __builtin_clz(b)) cout << "-1\n";↵
        else if(a == b) cout << "0\n";↵
        else{↵
            vector<int> val;↵
            for(int i = 0; i < 31; i++){↵
                int x = (1 << i);↵
                if(x <= a && (a & x) == 0) a += x, val.push_back(x);↵
            }↵
            for(int i = 0; i < 31; i++){↵
                int x = (1 << i);↵
                if(x <= a && (b & x) == 0) val.push_back(x);↵
            }↵
            cout << val.size() << '\n';↵
            for(auto z : val) cout << z << ' ';↵
            cout << '\n';↵
        }↵
    }↵
}↵

~~~~~↵


</spoiler>↵



D↵

Idea: [user:wakanda-forever,2025-10-10]↵
Preparation: [user:wakanda-forever,2025-10-10]↵

<spoiler summary = "Solution">↵
We denote ↵

$$ \operatorname{query}(1, l, r) = p_l + p_{l + 1} \dots + p_r $$↵
$$ \operatorname{query}(2, l, r) = a_l + a_{l + 1} \dots + a_r $$↵

Now, let us try to find $l$ first.↵

Consider two additional arrays representing the prefix sums of the arrays $p$ and $a$, defined as follows:↵

$$↵
\mathrm{pref\_sum\_p}[i] = p_1 + p_2 + \dots + p_i, \quad 1 \le i \le n↵
$$↵

$$↵
\mathrm{pref\_sum\_a}[i] = a_1 + a_2 + \dots + a_i, \quad 1 \le i \le n↵
$$↵

Analysing these, we can say that $\text{pref\_sum\_a}[i] \ge \text{pref\_sum\_p}[i]$ for all $i$. In fact, the inequality holds true only when $l \le i \le n$.↵

Thus, we can binary search for $l$.↵

At each stage, we make $2$ queries $\operatorname{query}(1, 1, \text{mid})$ and $\operatorname{query}(2, 1, \text{mid})$, and by comparing these, we can adjust $\text{left}$ and $\text{right}$ in binary search.↵

We can also find $r$ by querying suffixes in a similar way, but that would take a total of $4 \cdot \lceil \log_2(n) \rceil$ queries. This exceeds the query limit.↵

Instead, we can query the whole array once and find $r$. In other words, ↵
$$ \operatorname{query}(2, 1, n) - \operatorname{query}(1, 1, n) = r - l + 1 $$↵

So, after finding $l$, we can find $r$ in $2$ queries. Total queries will be equal to $2 \cdot \lceil \log_2(n) \rceil + 2$ ($ < 40$).↵

Time Complexity: $O(\log_2(n))$ per testcase.↵
</spoiler>↵

<spoiler summary = "Implementation">↵

~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵

#define ll long long↵

ll query(int type, int l, int r){↵
    ll x;↵
    cout << type << ' ' << l << ' ' << r << flush << endl;↵
    cin >> x;↵
    return x;↵
}↵
 ↵
int main(){↵
 ↵
    int t;↵
    cin >> t;↵
 ↵
    while(t--){↵
        ↵
        int n;↵
        cin >> n;↵

        ll sum = query(2, 1, n);↵
        sum -= ((n * (n + 1)) / 2);↵

        ll diff = sum - 1;↵

        int l = 1, r = n;↵

        while(l < r){↵
            int md = (l + r) / 2;↵
            ll val1 = query(1, 1, md);↵
            ll val2 = query(2, 1, md);↵

            if(val1 < val2) r = md;↵
            else l = md + 1;↵
        }        ↵

        cout << "!" << ' ' << l << ' ' << diff + l << flush << endl;↵

    }↵
}↵

~~~~~↵


</spoiler>↵



E↵

Idea: [user:wuhudsm,2025-10-10]↵
Preparation: [user:wakanda-forever,2025-10-10]↵

<spoiler summary = "Solution">↵
Instead of carefully choosing all $k$ elements individually, it is sufficient to pick <b>three distinct integers</b> $x$, $y$, and $z$ and repeat them cyclically — that is, append↵

$$x, y, z, x, y, z, \dots$$↵

until we perform $k$ operations. For $n \ge 3$, we can always find such $x$, $y$, $z$ that add no extra palindromic subarrays.↵

Now let's try to find such integers $x$, $y$, $z$. There will be two cases.↵

<b>Case 1</b>: $a$ is a permutation of ${1,2,3, \dots ,n}$.↵

If the array $a$ is a permutation, we can simply choose the first three elements of $a$ for the construction. That is, let $x = a_1$, $y = a_2$, and $z = a_3$.↵
Since all elements in a permutation are distinct, these choices guarantee that $x$, $y$, and $z$ are distinct and add no extra palindromic subarrays.↵

<b>Case 2</b>: $a$ is not a permutation of ${1,2,3, \dots ,n}$.↵

If the array $a$ is not a permutation, we can choose $x$ to be any integer that does not appear in $a$. Let $z$ be the last element of the array, and choose $y$ as any integer different from both $x$ and $z$. These three numbers will always be distinct and add no extra palindromic subarrays.↵

Time Complexity: $O(n + k)$ per testcase.↵
</spoiler>↵

<spoiler summary = "Implementation">↵

~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
 ↵
int main(){↵
 ↵
    int t;↵
    cin >> t;↵
 ↵
    while(t--){↵
        ↵
        int n, k;↵
        cin >> n >> k;↵

        vector<int> a(n), cnt(n + 1, 0);↵
        for(int i = 0; i < n; i++) cin >> a[i], cnt[a[i]]++;↵

        int x = -1;↵
        for(int i = 1; i <= n; i++) if(cnt[i] == 0){↵
            x = i;↵
            break;↵
        }↵

        if(x == -1){↵
            for(int i = 0; i < k; i++) cout << a[n - 3 + (i % 3)] << ' ';↵
            cout << '\n';↵
        }↵
        else{↵
            int y = -1;↵
            for(int i = 1; i <= n; i++) if(i != x && i != a[n - 1]){↵
                y = i;↵
                break;↵
            }↵
            vector<int> v = {x, y, a[n - 1]};↵
            for(int i = 0; i < k; i++) cout << v[i % 3] << ' ';↵
            cout << '\n';↵
        }↵

    }↵
}↵

~~~~~↵


</spoiler>↵



F↵

Idea: [user:tamzid1,2025-10-13], [user:wuhudsm,2025-10-13], [user:wakanda-forever,2025-10-13]↵
Preparation: [user:wakanda-forever,2025-10-10]↵

<spoiler summary = "Solution">↵
Note that if $[0,2,1]$ is a subsequence of permutation $p$, any interval that includes $0$ and $1$ must also include $2$. This implies that $\operatorname{mex}$ of any interval will not be equal to $2$. So, $2 \notin M$. Hence, $\operatorname{mex}(M) \le 2$.↵

Thus, we can always ensure that $\operatorname{mex}(M) \le 2$. Now, we only need to check when $\operatorname{mex}(M) = 0$ and $\operatorname{mex}(M) = 1$ are possible.↵

For $\operatorname{mex}(M)$ to be equal to $0$, $\operatorname{mex}$ of every interval must be positive. So, every interval must include $0$. This is possible only when all intervals intersect at a common point &mdash; that is, there exists at least one point that lies within every interval. Then we place $0$ at some common point and fill the remaining permutation.↵

Otherwise, for $\operatorname{mex}(M)$ to be equal to $1$, $\operatorname{mex}$ of each interval must not be equal to $1$. To ensure this, we have to place $0$ and $1$ in such a way that if an interval includes $0$, it must also include $1$. This is possible if there exists a point that is not simultaneously the starting point of one interval and the ending point of another. In other words, we should be able to find a position that does not act as both a left and a right boundary. Then we place $0$ at such a point and $1$ adjacent to it.↵

Else, we place $[0,2,1]$ as a subsequence first and then build the remaining permutation.↵

Time Complexity: $O(n + m)$ per testcase.↵
</spoiler>↵

<spoiler summary = "Implementation">↵

~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
#define int long long↵
#define INF (int)1e18↵

void Solve() ↵
{↵
    ↵
    int n, m; cin >> n >> m;↵
    ↵
    vector <int> l(m), r(m), f(n + 1), st(n + 1, 0), en(n + 1);↵
    for (int i = 0; i < m; i++){↵
        cin >> l[i] >> r[i];↵
        st[l[i]] = 1;↵
        en[r[i]] = 1;↵
        for (int j = l[i]; j <= r[i]; j++){↵
            f[j]++;↵
        }↵
    }↵
    ↵
    vector <int> ans(n + 1, -1);↵
    ↵
    auto fill = [&](){↵
        vector <bool> used(n, false);↵
        for (int i = 1; i <= n; i++) if (ans[i] != -1) used[ans[i]] = true;↵
        ↵
        int p = 0;↵
        for (int i = 1; i <= n; i++){↵
            if (ans[i] == -1){↵
                while (used[p]) p++;↵
                ↵
                ans[i] = p;↵
                used[p] = true;↵
            }↵
        }↵
        ↵
        for (int i = 1; i <= n; i++){↵
            cout << ans[i] << " \n"[i == n];↵
        }↵
    };↵
    ↵
    for (int i = 1; i <= n; i++){↵
        if (f[i] == m){↵
            int ptr = 1;↵
            ans[i] = 0;↵
            ↵
            fill();↵
            return;↵
        }↵
    }↵
    ↵
    for (int i = 1; i < n; i++){↵
        if (en[i] == 0){↵
            ans[i] = 0;↵
            ans[i + 1] = 1;↵
            fill();↵
            return;↵
        }↵
        ↵
        if (st[i + 1] == 0){↵
            ans[i] = 1;↵
            ans[i + 1] = 0;↵
            fill();↵
            return;↵
        }↵
    }↵
    ↵
    assert(n >= 3);↵
    ans[1] = 0;↵
    ans[2] = 2;↵
    ans[3] = 1;↵
    ↵
    fill();↵
}↵

int32_t main() ↵
{↵
    ios_base::sync_with_stdio(0);↵
    cin.tie(0);↵
    int t = 1;↵
    cin >> t;↵
    for(int i = 1; i <= t; i++) ↵
    {↵
        Solve();↵
    }↵
    ↵
    return 0;↵
}↵
~~~~~↵


</spoiler>↵



G↵

Idea: [user:wakanda-forever,2025-10-10]↵
Preparation: [user:wakanda-forever,2025-10-10]↵

<spoiler summary = "Solution">↵
We have to construct a tree with $n$ vertices such that $S = \sum_{\{u, v\} \in E} (u \cdot v)$ is a perfect square.↵

Instead of making it any random perfect square, let's try to make $S = (f(n))^2$ where $f(n)$ is an integer function of $n$.↵

Now, let's check if we can make $f(n) = n$. For $n = 5$, we can consider the following tree↵

$$5-1-2-3-4$$↵

where $S = 25 = (5)^2$.↵

Now that we know we have a tree $T$ with $n$ ($=5$) vertices having $S = n^2$. Using this, let's try to make a tree $T`$ with $n + 1$ vertices such that $S` = (n + 1)^2$. Note that $S` - S = 2n + 1$. So, while constructing $T`$, we have to add a new vertex $(n + 1)$ and also adjust this extra sum $2n + 1$.↵

We can achieve this in the following manner:↵

- add an edge between $1$ and $n + 1$,↵
- remove the edge between $1$ and $n$,↵
- add an edge between $2$ and $n$.↵

This analogy can be extended for all $n \ge 5$. Such trees have the following structure:↵

<p align="center">↵
  <img src="/predownloaded/8a/88/8a88f790f81cf65182f36cf963f910ef0c9a3c54.png">↵
</p>↵


So, we can always make $S = n^2$ for all $n \ge 5$. For $n < 5$, we can just print sample outputs.↵

One can also assume $f(n) = n + 1$ and construct a similar solution with $S = (n + 1)^2$.↵

Time Complexity: $O(n)$ per testcase.↵


</spoiler>↵

<spoiler summary = "Implementation">↵

~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
 ↵
int main(){↵
 ↵
    int t;↵
    cin >> t;↵
 ↵
    while(t--){↵
 ↵
        int n;↵
        cin >> n;↵
        ↵
        if(n == 2){↵
            cout << -1 << '\n';↵
            continue;↵
        }↵
 ↵
        if(n == 3){↵
            cout << "1 3\n2 3\n";↵
            continue;↵
        }↵
 ↵
        if(n == 4){↵
            cout << "1 2\n3 1\n4 1\n";↵
            continue;↵
        }↵
 ↵
        cout << "1 2\n";↵
        cout << "2 3\n";↵
        cout << "3 4\n";↵
 ↵
        cout << "1 " << n << '\n';↵
 ↵
        for(int i = 5; i < n; i++) cout << 2 << ' ' << i << '\n';↵
    }↵
}↵

~~~~~↵


</spoiler>↵



H↵

Idea: [user:wuhudsm,2025-10-10]↵
Preparation: [user:wuhudsm,2025-10-10]↵

<spoiler summary = "Solution">↵
Will be added soon.↵
</spoiler>↵

<spoiler summary = "Implementation">↵
Will be added soon.↵
</spoiler>↵

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en21 English wuhudsm 2025-10-25 19:23:50 350
en20 English wuhudsm 2025-10-18 02:23:50 52
en19 English wuhudsm 2025-10-18 02:21:07 367
en18 English wuhudsm 2025-10-18 02:12:40 5
en17 English wuhudsm 2025-10-18 02:11:33 2
en16 English wuhudsm 2025-10-18 02:10:04 10784
en15 English wakanda-forever 2025-10-17 20:35:47 112
en14 English wakanda-forever 2025-10-17 19:58:05 0 (published)
en13 English wakanda-forever 2025-10-17 19:57:15 38
en12 English wakanda-forever 2025-10-17 19:56:25 86
en11 English wakanda-forever 2025-10-13 05:02:37 260
en10 English wakanda-forever 2025-10-13 04:51:55 24
en9 English wakanda-forever 2025-10-10 20:17:03 88
en8 English wakanda-forever 2025-10-10 16:17:09 1170
en7 English wakanda-forever 2025-10-10 15:27:14 1486
en6 English wakanda-forever 2025-10-10 11:57:25 9
en5 English wakanda-forever 2025-10-10 11:50:58 1260
en4 English wakanda-forever 2025-10-10 11:25:40 3664
en3 English wakanda-forever 2025-10-10 11:04:43 8087 Tiny change: 'tion">\n\n</spoi' -> 'tion">\n\n`hi`\n\n</spoi'
en2 English wakanda-forever 2025-10-10 10:33:58 2
en1 English wakanda-forever 2025-10-10 10:32:48 1552 Initial revision (saved to drafts)