2108A - Перестановочный прогрев
Автор: eugenechka.boyko.2_0-0
Начнём с $$$p = [1, 2, 3, \dots, n]$$$. Для этой $$$p$$$ значение $$$f(p) = 0$$$.
Будем перемещать $$$n$$$ в начало по одной позиции за раз. Легко заметить, что на каждом шаге значение функции увеличивается на $$$2$$$.
Теперь переместим $$$n - 1$$$ на вторую позицию, затем $$$n - 2$$$ на третью и так далее, пока не получим $$$p = [n, n - 1, \dots, 2, 1]$$$. Для этой перестановки $$$f(p) = \lfloor \frac{n^2}{2} \rfloor$$$.
В процессе мы получили все чётные значения от $$$0$$$ до $$$\lfloor \frac{n^2}{2} \rfloor$$$, поскольку на каждом шаге прибавляли по $$$+2$$$.
Докажем, что другие значения получить невозможно.
Во-первых, очевидно, что нельзя получить значение меньше $$$0$$$ или больше $$$\lfloor \frac{n^2}{2} \rfloor$$$.
Во-вторых, мы можем получить только чётные значения, потому что каждый свап двух элементов изменяет значение функции на чётное число.
Получаем ответ: $$$\lfloor \frac{n^2}{4} \rfloor + 1$$$.
Сложность: $$$\text{O}(1)$$$.
#include <iostream>
#include <vector>
using namespace std;
typedef long long int ll;
#define SPEEDY std::ios_base::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0);
#define forn(i, n) for (ll i = 0; i < ll(n); ++i)
void solution(){
ll n;cin>>n;
ll k=n/2;
if (n%2){cout<<k*(k+1)+1;return;}
cout<<k*k+1;
}
int main() {
SPEEDY;
int t; cin>>t;
while (t--){
solution();
cout << '\n';
} return 0;
}
2108B - Разложение в сумму
Автор: eugenechka.boyko.2_0-0
Пусть $$$x \gt 1$$$, обозначим за $$$c$$$ количество единичных битов в его двоичной записи. Ясно, что при $$$n \le c$$$ нам будет выгодно просто раскидать по элементам массива разные степени двойки, в результате получив минимально достижимую сумму $$$x$$$. Если же $$$n \gt c$$$, то нам очевидно будет выгодно добавить в лишние $$$n-c$$$ элементов только единицы, при этом в случае, если $$$n-c$$$ нечётно, нам придется также добавить дополнительную единицу в один из $$$c$$$ блоков со степенями двойки, чтобы $$$\text{XOR}$$$ всех единиц стал равен $$$x$$$ $$$\text{mod}$$$ $$$2$$$.
Если $$$x=1$$$, то при нечетном $$$n$$$ мы очевидно просто заполним все элементы массива единицами, в противном случае нам потребуется использовать пару $$$[2, 3]$$$, $$$\text{XOR}$$$ которой равен $$$1$$$, получив наименьший счёт $$$n+3$$$.
В оставшемся случае с $$$x=0$$$ ситуация почти идентична предыдущей с тем исключением, что не существует подходящего примера для $$$n=1$$$ (и этот случай является единственным, имеющим ответ $$$-1$$$), то есть для чётного $$$n$$$ ответом будет само $$$n$$$, а иначе — $$$n+3$$$ (так как мы используем тройку $$$1 \oplus 2 \oplus 3 = 0$$$).
Асимптотика $$$\text{O}(1)$$$ на тест.
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
void solution(){
int n,x;cin>>n>>x;
int bits=__builtin_popcountll(x);
if (n<=bits){cout<<x;return;}
if ((n-bits)%2==0)cout<<x+n-bits;
else{
if (x>1){cout<<x+n-bits+1;return;}
if (x==1){cout<<n+3;return;}
else{
if (n==1){cout<<-1;return;}
else cout<<n+3;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
cin>>t;
while (t--){
solution();
cout << '\n';
} return 0;
}
2108C - Побег Нео
Автор: suprend
Заметим, что подряд идущие кнопки с одинаковым весом не влияют на ответ, поэтому для такой последовательности кнопок оставим только одну из них.
В получившемся массиве находим пики (локальные максимумы — элементы, которые строго больше обоих соседей). Количество таких пиков и является ответом, так как:
- Каждый пик отделен от других более маленькими элементами. Поэтому попасть в пик можно только создав клона в нём.
- Если были в кнопке, можем в нее вернуться.
- В любой элемент кроме пиков гарантированно можно попасть из большего соседа, так как мы уже посещали его. Поэтому создание клонов во всех остальных элементах не требуется
Сложность: $$$\text{O}(n)$$$
#include <iostream>
#include <vector>
using namespace std;
int main() {
int tt = 1;
cin >> tt;
while(tt--){
int n; cin >> n;
vector<int> a;
a.push_back(-1e9);
for (int i = 0; i < n; i++){
int x; cin >> x;
if (a.back() == x);
else a.push_back(x);
}
a.push_back(-1e9);
int ans = 0;
for (int i = 1; i < a.size() - 1; i++)
if (a[i - 1] < a[i] && a[i] > a[i + 1]) ans++;
cout << ans << endl;
}
}
2108D - Найти склейку в стоге чисел
Автор: m3tr0
Пусть $$$k = 4$$$ и загадан массив:
[ 2 4 3 1 2 4 3 1 2 1 3 2 4 1 3 2 4 1 ]
Для наглядности разобьём его на группы по $$$k$$$ элементов:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 ]
По условию, длины левой и правой частей как минимум $$$k$$$. Запросим левые $$$k$$$ и правые $$$k$$$ элементов. Будем отмечать красным все элементы левого массива, а синим — все элементы правого:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 ]
Дополним наш массив двумя числами справа (для наглядности перестановок):
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 3 2 ]
Мы получили перестановки в "нормированном" виде: $$$[2, 4, 3, 1]$$$ и $$$[4, 1, 3, 2]$$$. Возьмём любую позицию, на которой элементы в перестановках различаются. Пусть это будет вторая позиция. Отметим все элементы на выбранных позициях в загаданном массиве:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 3 2 ]
Среди них находим граничные элементы бинарным поиском за $$$\log \frac{n}{k}$$$ запросов:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 3 2 ]
Далее рассмотрим отрезок между этими граничными элементами:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 3 2 ]
Нам не интересны позиции, которые совпадают в обоих перестановках (в нашем случае это только третья позиция). Отбросим элементы на этих позициях:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 3 2 ]
Среди рассматриваемых элементов бинарным поиском находим граничные за $$$\log k$$$ запросов:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 3 2 ]
Если между граничными элементами есть "ничейные", то однозначного решения не существует и выводим $$$-1$$$. В нашем случае таких элеметов нет, задача решена:
[ 2 4 3 1 ] [ 2 4 3 1 ] [ 2 1 3 2 ] [ 4 1 3 2 ] [ 4 1 ]
Итоговая сложность: $$$2k + \log \frac{n}{k} + \log k$$$ запросов.
#include <cstdio>
#include <cstdlib>
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
typedef long long l;
l a[55], b[55], ui[55];
l ask(l v) {
printf("? %lld\n", v + 1);
fflush(stdout);
l t; scanf("%lld", &t);
return t;
}
void noans() {
printf("! -1\n");
fflush(stdout);
}
void ans(l a, l b) {
printf("! %lld %lld\n", a, b);
fflush(stdout);
}
void solve() {
l n, k; scanf("%lld %lld", &n, &k);
for (l i = 0; i < k; ++i) a[i] = ask(i);
for (l i = n - k; i < n; ++i) b[i % k] = ask(i);
l uc = 0;
for (l i = 0; i < k; ++i) if (a[i] != b[i]) ui[uc++] = i;
if (!uc) {
if (n == k * 2) ans(k, k);
else noans();
return;
}
l le = ui[0], ri = ui[0] + (n - 1) / k * k;
while (le + k != ri) {
l mid = le + (ri - le) / k / 2 * k;
if (ask(mid) == a[ui[0]]) le = mid;
else ri = mid;
}
l lee = 0, rii = uc;
while (lee + 1 != rii) {
l mid = (lee + rii) / 2;
if (ask(le - ui[0] + ui[mid]) == a[ui[mid]]) lee = mid;
else rii = mid;
}
l pos1 = MAX(le - ui[0] + ui[lee], k - 1);
l pos2 = MIN(le - ui[0] + ((rii == uc) ? (ui[0] + k) : ui[rii]), n - k);
if (pos1 + 1 != pos2) { noans(); return; }
ans(pos2, n - pos2);
}
int main() {
l t; scanf("%lld", &t);
while (t--) solve();
}
2108E - Разборки с ёлкой
Автор: eugenechka.boyko.2_0-0
Предположим, что мы уже удалили одно из рёбер из исходного дерева, тогда у нас осталось какое-то дерево на чётном числе вершин $$$n - 1$$$. Заметим, что максимальная возможная сумма расстояний между одноцветными шариками в нём будет достигаться в том случае, если для каждого из его рёбер все вершины его поддерева наименьшего размера будут разных цветов, поскольку тогда оно будет учитываться в ответе максимальное для него число раз, то есть $$$\min(a, b)$$$, где $$$a$$$ и $$$b$$$ — размеры поддеревьев, связанных этим ребром, ведь пройти больше путей через это ребро, очевидно, не может.
Супер, а давайте тогда подвесим наше дерево за его центроид — вершину, разделяющую дерево на поддеревья, размер которых не превышает половину его размера. Можно доказать, что такая вершина существует в любом дереве (если же их две, то подвесим за любую из них).
Теперь разделим вершины на группы по принадлежности к поддеревьям детей центроида, добавив сам центроид в группу наименьшего размера. Заметим, что размеры всех групп всё ещё не превосходят $$$\frac{n - 1}{2}$$$, а значит, мы можем разбить их на пары таким образом, чтобы в каждой паре обе вершины были в разных группах. Это можно сделать жадно с использованием кучи за $$$O(n \log n)$$$ либо запустив DFS из центроида и раскрашивая вершины в цвета по модулю $$$\frac{n - 1}{2}$$$ (очевидно, что при таком подходе ни в одной группе не окажется двух вершин одного цвета) со сложностью $$$O(n)$$$.
Таким образом, нам остаётся лишь понять, при удалении какого из рёбер значение суммы размеров минимальных поддеревьев по всем рёбрам исходного дерева уменьшится наименее всего. Заметим, что поскольку в начале дерево состоит из нечётного числа вершин, его центроид определяется однозначно и не изменится при удалении любого из рёбер. В то же время, поскольку все пути проходят через центроид, сумму их длин можно переписать как сумму расстояний до центроида. Тогда сделаем два утверждения:
- Удалить лист выгоднее, чем что-то другое;
- Среди всех листов наиболее выгодно удалить лист, ближайший к центроиду.
Второе утверждение моментально следует из первого и замечания выше, поэтому нас интересует только первое. Однако это довольно очевидно, поскольку при удалении ребра, помимо вычитания глубины его ближайшей вершины, на один уменьшатся глубины всех вершин в его поддереве, откуда всегда выгоднее будет удалять более глубокие рёбра, чем менее глубокие.
В итоге, с поиском центроида за $$$O(n)$$$ получаем асимптотику $$$O(n \log n)$$$ (при использовании кучи) или $$$O(n)$$$.
#include <cstdio>
#include <vector>
#define S 200005
using namespace std;
typedef long long l;
l coloring[S], centroid, best, best_dist, n, color;
vector<vector<l>> g;
l search_centroid(l u, l from) {
l sum = 0;
bool f = true;
for (l v : g[u]) if (v != from) {
l t = search_centroid(v, u);
if (t > n / 2) f = false;
sum += t;
}
if (f && n - 1 - sum <= n / 2) centroid = u;
return sum + 1;
}
void make_coloring(l u, l from, l dist) {
coloring[u] = (color++) % (n / 2) + 1;
if (g[u].size() == 1 && dist < best_dist) {
best_dist = dist;
best = u;
}
for (l v : g[u]) if (v != from)
make_coloring(v, u, dist + 1);
}
void solve() {
centroid = -1, best_dist = S, color = 0;
scanf("%lld", &n);
g.assign(n, vector<l>());
for (l i = 0; i < n - 1; ++i) {
l u, v; scanf("%lld %lld", &u, &v); --u, --v;
g[u].push_back(v); g[v].push_back(u);
}
search_centroid(1543 % n, -1);
make_coloring(centroid, -1, 0);
l bbest = max(best, g[best][0]);
coloring[centroid] = coloring[bbest];
coloring[bbest] = 0;
printf("%lld %lld\n", best + 1, g[best][0] + 1);
for (l i = 0; i < n; ++i) {
if (i) printf(" ");
printf("%lld", coloring[i]);
}
printf("\n");
}
int main() {
l tc; scanf("%lld", &tc);
while (tc--) solve();
}
2108F - Падшие башни
Автор: m3tr0
Можно показать, что для любого массива $$$A$$$, который мы получим в итоге после обрушения всех $$$n$$$ башен, мы также можем получить в итоге любой другой массив $$$B$$$, элементы которого не превышают элементы $$$A$$$. Строгое формальное доказательство приведено в спойлере ниже, здесь будет краткое. Пусть на $$$i$$$-ю башню упало $$$k$$$ блоков за всё время. Тогда, чтобы её высота в итоговом массиве была равна $$$A_i$$$, то $$$A_i$$$ блоков должны упасть после её обрушения, а остальные $$$k - A_i$$$ блоков — до. Тогда мы всегда можем поменять порядок падения башен таким образом, чтобы её высота была равна $$$B_i \leq A_i$$$. То есть мы сделаем так, чтобы $$$B_i$$$ башен упали на башню $$$i$$$ после её обрушения, а $$$k - B_i$$$ — до.
Из этого утверждения о возможности получить меньший массив следует два факта:
Для любого ответа $$$\text{MEX} = x$$$ мы также можем получить ответ $$$x - 1$$$. Значит, мы можем применить бинарный поиск по ответу.
Для любого ответа $$$\text{MEX} = x$$$ мы можем получить его в виде $$$[0, 0, 0, 0, \ldots, 1, 2, 3, \ldots, x - 1]$$$. Значит, на каждой итерации бинарного поиска по ответу нам нужно проверить возможность получения такого массива. Для этого пройдёмся слева направо по башням, отслеживая количество кубиков, которые в какой-то момент на неё упадут и обрушая каждую башню после требуемого количества кубиков, упавших на неё. Отслеживать количество кубиков оптимальнее всего с помощью метода scanline.
Всего у нас $$$\text{O}(\log n)$$$ итераций в бинарном поиске по ответу и $$$\text{O}(n)$$$ операций на каждой итерации.
Итоговая сложность — $$$\text{O}(n \log n)$$$
Пусть массив $$$a$$$ длины $$$n$$$ — некоторый набор входных данных к задаче.
Пусть $$$r$$$ и $$$r'$$$ — массивы длины $$$n$$$ такие, что $$$\forall i : 0 \leq r'_i \leq r_i$$$.
Утверждение 1: Пусть $$$\exists$$$ перестановка $$$p$$$ такая, что башня с индексом $$$i$$$ обрушается $$$p_i$$$-ая по порядку, и в результате получается массив $$$r$$$. Тогда $$$\exists$$$ перестановка $$$p'$$$ такая, что башня с индексом $$$i$$$ обрушается $$$p'_i$$$-ая по порядку, и в результате получается массив $$$r'$$$.
$$$\square$$$
Пусть $$$s_i$$$ — суммарное количество башен, которые когда-либо падали на позицию $$$i$$$ при обрушении башен в порядке $$$p$$$. Отметим, что из них $$$r_i$$$ башен были обрушены позже, чем $$$i$$$-я, а остальные — раньше. А высота башни $$$i$$$ в момент обрушения равна $$$a_i + (s_i - r_i)$$$.
Предположение индукции: Существует перестановка $$$p^{(k)}$$$ чисел от $$$1$$$ до $$$k \leq n$$$ такая, что если обрушить $$$i$$$-ю башню $$$p^{(k)}_i$$$-ой по счёту, то:
В итоге на $$$i$$$-й позиции будет башня высоты $$$r'_i$$$.
Количество (пусть $$$s^{(k)}_i$$$) башен, которые упали на позицию $$$i$$$ при обрушении башен в порядке $$$p^{(k)}$$$, больше либо равно чем $$$s_i$$$.
База индукции: Перестановка $$$p^{(1)} = [1]$$$. После обрушения высота башни становится равной $$$0$$$, поэтому $$$r'_1 = r_1 = 0$$$ в любом итоговом массиве. $$$s^{(1)}_1 = s_1 = 0$$$.
Переход индукции: Пусть перестановка $$$p^{(k - 1)}$$$ существует. Докажем существование $$$p^{(k)}$$$.
$$$\forall i \leq k - 1$$$ высота $$$i$$$-й башни в момент обрушения при порядке $$$p^{(k - 1)}$$$ не меньше, чем при порядке $$$p$$$:
Из этого следует, что при обрушении в порядке $$$p^{(k - 1)}$$$ на позицию $$$k$$$ упадёт не менее чем $$$s_k$$$ башен (пусть их количество равно $$$x \geq s_k \geq r'_k$$$). Ведь высоты в момент обрушения всех башен $$$i \lt k$$$ не изменились либо стали больше.
Пусть $$$x \gt r'_k$$$ и башня $$$j$$$ — это $$$(x - r'_k)$$$-ая по счёту башня из упавших на позицию $$$k$$$. Тогда обрушим башню $$$k$$$ сразу после башни $$$j$$$. Если же $$$x = r'_k$$$, то обрушим башню $$$k$$$ первой. В обоих случаях после обрушения $$$k$$$ на неё упадёт $$$r'_k$$$ башен и её высота станет равна $$$r'_k$$$.
То есть, формально, при $$$x \gt r'_k$$$ переставновка $$$p^{(k)}$$$ строится следующим образом:
$$$\forall i \lt k : p^{(k - 1)}_i \leq p^{(k - 1)}_j \Rightarrow p^{(k)}_i = p^{(k - 1)}_i$$$
$$$p^{(k)}_k = p^{(k - 1)}_j + 1$$$
$$$\forall i \lt k : p^{(k - 1)}_i \gt p^{(k - 1)}_j \Rightarrow p^{(k)}_i = p^{(k - 1)}_i + 1$$$
А при $$$x = r'_k$$$:
$$$p^{(k)}_k = 1$$$
$$$\forall i \lt k : p^{(k)}_i = p^{(k - 1)}_i + 1$$$
Массив $$$s^{(k)}$$$ строится как $$$\forall i \lt k : s^{(k)}_i = s^{(k - 1)}_i$$$ и $$$s^{(k)}_k = x$$$.
Индукция доказана. Значит положим $$$p' = p^{(n)}$$$, и утверждение доказано.
$$$\blacksquare$$$
Следствие 1: Если мы можем получить $$$\text{MEX}(r) \gt 0$$$ в качестве ответа на задачу при итоговом массиве $$$r$$$, то мы также можем получить $$$\text{MEX}(r) - 1$$$ в качестве ответа на задачу.
$$$\square$$$
Положим $$$r'_i = \max(0, r_i - 1)$$$. Тогда, по утверждению 1, $$$r'$$$ возможно получить как итоговый массив. $$$\text{MEX}(r') = \text{MEX}(r) - 1$$$.
$$$\blacksquare$$$
Следствие 2: Если мы можем получить $$$\text{MEX}(r)$$$ в качестве ответа на задачу при итоговом массиве $$$r$$$, то мы можем получить $$$\text{MEX}(r') = \text{MEX}(r)$$$ при итоговом массиве $$$r'$$$, где $$$r'_i = \max(0, (\text{MEX}(r) - 1) - (n - i))$$$.
$$$\square$$$
По утверждению 1, $$$r'$$$ возможно получить как итоговый массив.
$$$\blacksquare$$$
Можно применить бинарный поиск по ответу (из следствия 1), а на каждой его итерации при проверке ответа $$$x$$$ проверять, можем ли мы получить итоговый массив $$$r$$$ вида $$$r_i = \max(0, (x - 1) - (n - i))$$$ (из следствия 2).
#include <cstdio>
#include <algorithm>
#include <cstring>
#define S 100005
typedef long long l;
l a[S], d[S], n;
bool check(l ans) {
memset(d, 0, sizeof(l) * n);
l acc = 0;
for (l i = 0; i < n; ++i) {
acc -= d[i];
l need = std::max(0LL, i - (n - ans));
if (acc < need) return false;
l end = i + a[i] + (acc++) - need + 1;
if (end < n) ++d[end];
}
return true;
}
void solve() {
scanf("%lld", &n);
for (l i = 0; i < n; ++i) scanf("%lld", &a[i]);
l le = 1, ri = n + 1, mid;
while (ri - le > 1) {
mid = (le + ri) / 2;
if (check(mid)) le = mid;
else ri = mid;
}
printf("%lld\n", le);
}
int main() {
l tc; scanf("%lld", &tc);
while (tc--) solve();
}









Автокомментарий: текст был обновлен пользователем eugenechka.boyko.2_0-0 (предыдущая версия, новая версия, сравнить).
Auto comment: topic has been updated by eugenechka.boyko.2_0-0 (previous revision, new revision, compare).
Shouldn’t it be, “each swap changes the answer by an even number”?
There is another nitpick as well. Sorry about these. Shouldn't it be n+3 NOT x+3 for Problem B?
Problem F is awesome, thanks for the contest!
As A participant I reeally enjoy thanks for your contest.
The solution for problem F is poetic
Problem A is an easier version of this.
Can you please tell me how you found this problem, or did you remember it from previous experience?
The funny thing is that if you look at my submissions I reviewed this problem very recently before the contest. I literally chuckled when I saw the problem in the contest.
please send some of your luck over to me via internet. :P
Can someone explain why this test case is -1?
n=12 k=4,
1 3 2 4 1 1 3 4 2 1 3 4
3 7 1 1 1 1 1 1 1 1 1 1 is also valid for this ,yes why is it -1 then ?
its not -1? assuming you're talking about b
Sorry, I am talking about D
oh mb
If you meant n=7,k=3
Then this is not valid since, there are not unique elements in the end k and start k elements.
its not -1, thats just not the optimal answer
here is correct construction
4+1, 1 (makes 4) then a bunch of 1s
thats 5+1+(12-2) = 16
Can someone explain how we "normalize" the permutation in D? I thought to use binary search to find the segment where A ends similar to the editorial in contest, but I got stuck on the fact that the last k elements are not necessarily $$$B_1, B_2, ..., B_k$$$
we are only interested in comparing elements whose indexes are modulo $$$k$$$. Therefore, for the last $$$k$$$ elements (they necessarily belong to the right array), we can take their values and indexes modulo $$$k$$$ and substitute them into a normalized permutation. That is, if $$$b'$$$ is the normalized permutation underlying the array $$$B$$$, then $$$\forall i \in \overline{n - k, n - 1} : b'[i~\%~k] = C[i]$$$. Indexing from $$$0$$$
I like sample in D
E is very good, thx for the contest
for D, also the diagrams were very helpful
Can you make the problem titles clickable such that they go to the problems, much like other editorials?
yeah, updated
I feel so bad when I read "it is easy to see" for Problem A because my dumb ass didnt see T__T
Loved the images in Problem D! I hope the other Authors take inspiration from you
317996659 Can you please tell me why this algorithm failed?
Your code fails for the following input:
Essentially, what's happening is that due to the
greater<>in your sorter, if two indices are equal, then the one on the right appears before the one on the left, which is easy to break (it sees the 1 at the 3rd position and says "Well no robot is to the left or right, so we need to place a robot here."). There is a "small" fix to your code that makes it AC though.Instead of trying to process it per element, why not when inserting, process which buttons that same robot can also press?
Shouldn’t it be, “each swap changes the answer by an even number”?
Ignore above comment. Meant to comment on the Editorial.
Thank you JaSonicPlusPlus . ACCEPTED 318064174. I got where it fails. I have to store just consecutive duplicates for one time . Again thank you & have a nice day.
D-F were amazing!
I became a pupil!
Why I think B is more difficult than C?
Just my opinion:
UPD: After an hour's thinking, I think $$$A\lt C$$$ now.
I really like the contest (in particular D and E, but finished E 5 min after the end ://).
My ($$$\mathcal O(n)$$$) solution for E (We don't need a centroid decomposition):
Removing one edge will always reduce the total score, but we want to minimize the reduction. If we remove an edge to a leaf, the "lost contribution" of that edge is $$$1$$$. The change of contribution of the other edges $$$w_1w_2$$$ is $$$-1$$$ if:
This means that we can do a simple DFS and pass the following values:
The score change can then be calculated as:
Note: This can be reduced to one score since $$$s_2 = t - 1 - s_3$$$, where $$$t$$$ is the total number of subtrees of size $$$ \gt \frac{n - 1}{2}$$$ while $$$s_3$$$ is the number of vertices with a subtree of size $$$ \gt \frac{n - 1}{2}$$$ on the path to the root, so we decrease $$$s_1$$$ if the subtree size is $$$\le \frac{n - 1}{2}$$$ and increase it if $$$ \gt \frac{n - 1}{2}$$$.
Since we are only running DFSs, the total runtime is $$$\mathcal O(n)$$$.
Submission with $$$s_1, s_2$$$ (Proof by AC)
Edit: Submission/Fixes
Thank you for the good contest.Yeah I got orange.
whoa.. so cool
My idea of E may be wrong.
First I thought of what if we don't need to delete an edge.I will find the centroid of the tree,let the centroid be root.Then just dfs to confirm there are no same color in each subtree.
And in this problem,I found the centroid,let it be root and dfs,then find the leaf with minimum height,delete the edge linking the leaf and its parent.Then just dfs to confirm there are no same color in each subtree.
I passed the sample and some tests,but was wrong on pretest 8,Could anybody explain where is wrong
318013026
2108A — Permutation Warm-Up
How to prove that max value of f(p) = floor((n^2) / 2).
From the editorial I can only understand that it is possible, but how to prove that it is max ?
I posted a proof lower =)
Can some one tell me where am i wrong in D, here is my Solution
Can some one tell me where am i wrong in D, here is my Solution
Editorial for A is so bad...
"For this p, f(p)=⌊n22⌋." Proof ?
"since we were adding +2 at each step" -> Wrong. Some steps do not change the value.
"Let’s prove that we can’t get any other values [...] it’s easy to see that" -> Is this a joke ?! Repeating your premise and claiming it's easy is no proof. This is actually the main difficulty of the problem.
"Second, we can only obtain even values, because each swap changes the answer by an odd number." Is the "odd" a typo for "even" ? Also, Proof ?
What's the point of pretending to prove anything, if what you'll say explicitely will be more trivial than what you dont bother to prove ? Just say one can guess this perm is optimal and prove by AC.
The value for the permutation given is sum(n-1-2k) with k from 0 to ceil(n-1/2)==floor(n/2)
Either you know the sum 0..N of odd numbers is N^2 or you can split the sum and use sum 0..N is N*(N+1)/2. Sure it's basic but not especially trivial for a div2A.
An optimal perm cannot have a number smaller than half in the first half and bigger than half in the second otherwise swapping them would give a higher answer. Let's consider the first half if there was a number lower than an other placed before this higher number we could increase the answer by swapping them. Same thing applies to the second half. We have proven the decreasing perm is optimal for n even. For n odd swapping the middle number doesnt change the answer if the above properties are respected (the displaced middle compensates exactly for the score lost)
I cant see anything elegant to prove that the answer is always even. We can take a permutation do a swap on it, and study each case if i and j are both greater or smaller than both pi and pj the answer is the same, if pi<=i<j<=pj or i<=pi<pj<=j we contribute to the opposite of what we used to the difference is twice the contribution. Lastly for i<=pi<=j<=pj the difference in contribution is 2pi-2j by just writing it out we can do similarly for pi<=i<=pj<=j. Since all permutations can be reached through a series of swaps for the 1..N perm, we have a proof.
Anyone has something simpler ?
We can use the fact that $$$|x| \equiv x \pmod{2}$$$ (it is either $$$x$$$ or $$$-x$$$, both of which satisfy the congruence). This gives that $$$|p_1 - 1| + |p_2 - 2| + \dots + |p_n - n| \equiv (p_1 + p_2 + \dots + p_n) - (1 + 2 + \dots + n) \equiv 0 \pmod{2}$$$.
Elegant !
Can any one explain me the no mans land condition given in the editorial ?
can any one explain me the "no mans land" condition given in the editorial for Problem D ?
It means that the elements between the boundaries do not definitively belong to the left nor the right array (no array claims it), because it matches the patterns for both arrays. An example is the last test case in the problem statement:
The pattern for A is 1 3 2 4, and for B is 1 3 4 2. Neither array can claim the elements between the boundaries (
1 3), because they match the pattern for the other array as well, and thus any split is valid.thx for contest<3 :((((((((((
thx for this awesome contest fr like it yea i didnt Register but e is so haaaaaaaaaard-_____-
A and D are interesting.
Could any tell me why D need binary twice
after we binary first we ' ll get an answer range which its len less 50
then we just find it straight isn t it?
i think that will be 3k + log(n / k), could anyone proof it ? or why its not right?
yeap this is one of the possible solutions
the editorial shows the optimal solution for 125 queries, but after testing we came to the conclusion that the best way would be to increase the available number of queries
respect for authors for amazing tutorial and notes. I hope such notes and tutorial will be in every round.
In Problem C,I used dp and binary search to solve it.
submission #317966737
Nice editorial.
Before this contest, I didn't even know that popcount existed, so I made a literal function to count the number of 1 bits in x
problem F is insane
Can anyone help me to findout mistake in my code in Problem D of this round . It is failing on some test case where answer should be -1 but my code is printing some number. Submission Id:323253380
solved ! I was checking the last condition wrong .
324755461 Can anyone tell why this code is failing?
Try this case:
Does there exist a Graph approach for
C, if yes then please comment down your approach with your accepted code.I am just curious because one of the tag of this question is showing graph.const int N = 2e5 + 10; int n, a[N]; PII b[N]; bool st[N]; **** int main(){ ** IOS; ** ** int _ = 1;** ** cin >> ;** ** while(--)** ** {** ** cin >> n;** ** for(int i = 1; i <= n; ++ i)** ** cin >> a[i], b[i] = {a[i], i}, st[i] = false;** ** sort(b + 1, b + 1 + n);** ** int cnt = 0;** ** for(int i = n; i >= 1; -- i)** ** {** ** int x = b[i].second;** ** if(!st[x])** ** st[x] = true, cnt++;** ** st[x — 1] = true, st[x + 1] = true;** ** }** ** cout << cnt << endl;** ** }** **** ** return 0;** } why C this way was wrong?
2108C - Neo's Escape I got scared after seeing the topics written in the problem tags of this question, but this is the easiest question of 1500 rating i have ever solved 368354382