Всем привет! Сегодня я хотел бы сделать разбор на те задачи, которые смог решить на сегодняшнем контесте.
Идея решения:
Так как синий цвет является доминантным, возможны два случая:
- Когда красных ≤ синих. В этом случае других вариантов нет: они должны располагаться в центре, а условие корректности выглядит так:
Unable to parse markup [type=CF_MATHJAX]
Тогда ответ "YES".
- Когда красных > синих. Здесь уже учитываем оба цвета. Чтобы расстановка существовала, должно выполняться:
Unable to parse markup [type=CF_MATHJAX]
В противном случае ответа нет.
Алгоритм:
- Считаем количество красных и синих.
- Проверяем описанные условия.
- Выводим "YES" или "NO".
Особенности:
- Ключевое — проверка на чётность.
- Других условий нет, всё сводится к паритету.
#include <iostream>
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define s second
#define f first
#define sort(x) sort(x.begin(),x.end());
using namespace std;
void bruh(){
ll n,k,x; cin >> n >> k >> x;
ll mx = max(k,x);
if((n-x)%2==1){
cout << "NO" << endl;
return;
}
if((n-k)%2==0 || k<x){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
}
int main()
{
ll t; cin >> t;
while (t--){
bruh();
}
}
Идея решения:
Мы хотим найти такое ( g > 1 ), что все элементы будут делиться на ( g ).
Ключевое наблюдение:
Именно поэтому берём $$$k+1$$$ в основу преобразования.
Алгоритм:
- Для каждого элемента корректируем его по формуле:
- Выводим новый массив как ответ.
Особенности:
- Связка $$$k$$$ и $$$k+1$$$ всегда взаимно просты, это гарантирует возможность построения решения.
- Изменение каждого элемента независимое, что упрощает задачу.
#include <iostream>
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define s second
#define f first
#define sort(x) sort(x.begin(),x.end());
using namespace std;
bool isPrime(ll n) {
if (n < 2) return false;
if (n == 2 || n == 3) return true;
if (n % 2 == 0) return false;
for (ll i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
void bruh(){
ll n,k; cin >> n >> k;
vector<ll> a(n);
for (ll i =0;i<n;i++){
cin >> a[i];
}
for (ll x: a){
cout << (x+(x%(k+1))*k) << " ";
}cout << endl;
}
int main()
{
ll t; cin >> t;
while (t--){
bruh();
}
}
Идея решения:
Нужно минимизировать сумму после того, как массив станет "хорошим". Под хорошим понимается, что для каждой тройки элементов с центром на чётной позиции выполняется:
Это условие автоматически гарантирует корректность для всех больших подотрезков, поэтому достаточно проверять только тройки.
Пошаговое рассуждение:
Берём любую тройку с центром на чётном индексе $$$i$$$. Если условие выполняется — идём дальше. Если нет — уменьшаем концы тройки так, чтобы оно выполнилось.
Чтобы уменьшения были минимальными:
- сначала корректируем правую границу ($$$a[i+1]$$$);
- если этого недостаточно, остаток убираем с левой границы ($$$a[i-1]$$$).
- Для последнего элемента массива ($$$i = n-1$$$) правого соседа нет, поэтому уменьшаем только левый:
Алгоритм:
- Проходим по всем чётным индексам массива.
- Проверяем условие для каждой тройки.
- При нарушении уменьшаем сначала правую, затем левую границу.
- Для последнего элемента отдельно обрабатываем случай без правого соседа.
- Считаем разницу сумм:
где $$$a[i]$$$ — изначальные значения, а $$$b[i]$$$ — новые после корректировок.
Особенности:
- Проверка на тройки достаточна — условие транзитивно для длинных отрезков.
- Стратегия "правый потом левый" всегда даёт минимизацию.
- Отдельный случай $$$i = n-1$$$ требует аккуратного разбора.
#include <iostream>
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define s second
#define f first
#define sort(x) sort(x.begin(),x.end());
using namespace std;
void bruh(){
ll n; cin >> n;
vector<ll> a(n);
for (ll i = 0;i<n;i++){
cin >> a[i];
}
vector<ll> test = a;
for (ll i = 1;i<n;i+=2){
if(i==n-1){
ll op = max(0LL,a[i-1]-a[i]);
a[i-1]-=op;
}else{
ll d = a[i-1]+a[i+1];
if(d>a[i]){
ll ost = d-a[i];
a[i+1]-=(min(a[i+1],ost));
ll ok = a[i-1]+a[i+1];
if(ok>a[i]){
a[i-1]-=ok-a[i];
}
}}
}
ll sm = 0;
for (ll i = 0;i<n;i++){
if(i%2==0){
sm+=test[i]-a[i];
}
// cout << a[i] << " ";
}
//cout << endl;
cout << sm << endl;
}
int main()
{
ll t; cin >> t;
while (t--){
bruh();
}
}



