Фанатский разбор Codeforces Round 1054 (Div. 3) A-E:)
Difference between ru14 and ru15, changed 0 character(s)
Всем привет, извиняюсь, что разбор вышел не в актуальное время, я попросту забыл его выпустить:(↵
↵
P>S: Если какая-то из задач все еще непонятна, то можете просмотреть код для полной ясности.↵
↵
<p align = "center">↵
<img src = "https://i.ibb.co.com/W4Yj3kfv/anime-cartoon-characters-cute-cats-spring-pictures-happy-cute-art-animals-kittens-pets-grap-1141449.jpg" width = "10" height = "10">↵
</p>↵
↵
----↵
↵
<spoiler summary="Задача А:">↵
Полное решение:↵
Давайте заметим, что если есть какое-то четное кол-во (-1), то в итоге все -1 превратятся в ↵
одну положительную единицу. ↵
↵
Поэтому посчитаем все такие (-1), и просто возьмем их кол-во по↵
модулю 2. ↵
↵
Это и будет частью ответа.↵
Дальше заметим, что если есть какое-то кол-во 0, ↵
↵
то с ними мы ничего не сделаем, ↵
а значит ↵
второй частью ответа просто будет кол-во 0.↵
Выведем наш ответ, как cnt1%2+cnt0, ↵
↵
где cnt1 &mdash; кол-во -1, а cnt2 &mdash; кол-во 0.↵
↵
Сложность: O(n)↵
↵
<spoiler summary="Code:">↵
↵
~~~~~↵
#include <iostream>↵
#include <bits/stdc++.h>↵
#define ll long long ↵
#define pb push_back↵
#define f first↵
#define s second↵
#define all(x) x.begin(),x.end()↵
using namespace std;↵
void bruh(){↵
  ll n; cin >> n;↵
  vector<ll> a(n);↵
  for (ll &x: a){↵
    cin >> x;↵
  }↵
  ll cnt = 0; ll cntt = 0;↵
  for (ll i = 0;i<n;i++){↵
    if(a[i]<0){↵
      cnt++;↵
    }else if(a[i]==0){↵
      cntt++;↵
    }↵
  }↵
  cout << (cnt%2)*2+cntt << endl;↵
}↵
int main() ↵
{↵
  ios::sync_with_stdio(false);↵
  cin.tie(0);↵
  ll t; cin >> t;↵
  while (t--){↵
    bruh();↵
  }↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
</spoiler>↵
↵
----↵
↵
<spoiler summary="Задача В:">↵
Полное решение:↵
Т.к нам нужно максимизировать наш ответ, ↵
↵
давайте просто возьмем самый максимальный элемент в пару↵
со вторым максимальным, итд.↵
↵
Для этого можно просто отсортировать массив.↵
↵
Выведем наш ответ.↵
↵
Сложность: O(nlogn)↵
↵
<spoiler summary="Code:">↵
↵
~~~~~↵
#include <iostream>↵
#include <bits/stdc++.h>↵
#define ll long long ↵
#define pb push_back↵
#define f first↵
#define s second↵
#define all(x) x.begin(),x.end()↵
using namespace std;↵
void bruh(){↵
  ll n; cin >> n;↵
  vector<ll> a(n);↵
  for (ll &x: a){↵
    cin >> x;↵
  }↵
  sort(all(a));↵
  ll l = 0; ll r = n-1;↵
  ll mx = 0;↵
  while (r>=0){↵
    ll diff = (abs(a[r]-a[r-1]));↵
    mx = max(mx,diff);↵
    r--;↵
    r--;↵
  }↵
  cout << mx << endl;↵
}↵
int main() ↵
{↵
  ios::sync_with_stdio(false);↵
  cin.tie(0);↵
  ll t; cin >> t;↵
  while (t--){↵
    bruh();↵
  }↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
</spoiler>↵
↵
----↵
↵
<spoiler summary="Задача С:">↵
Полное решение:↵
↵
Давайте заметим, что если до требуемого k, нет какого-то числа, то нам не остается ничего, ↵
↵
как просто добавить это число, так же если f(k)!=0, где f(x) &mdash;↵
↵
кол-во вхождений числа x в массив, то это число нужно заменить на какое-то другое тоже.↵
↵
Дальше стоит заметить, что вышеуказанные операции могут пересекаться, тогда ответом будет max(cnt,f(k)), где cnt &mdash; кол-во таких чисел от 0 до k, ↵
что вхождении в массив у этих элементов равна 0, т.е f(x) == 0.↵
↵
Выведем наш ответ.↵
↵
Сложность: O(n)↵
↵
<spoiler summary="Code:">↵
↵
~~~~~↵
#include <iostream>↵
#include <bits/stdc++.h>↵
#define ll long long ↵
#define pb push_back↵
#define f first↵
#define s second↵
#define all(x) x.begin(),x.end()↵
using namespace std;↵
void bruh(){↵
  ll n,k; cin >> n >> k;↵
  vector<ll> a(n);↵
  map<ll,ll> mp;↵
  for (ll i = 0;i<n;i++){↵
    cin >> a[i];↵
    mp[a[i]]++;↵
  }↵
  ll cnt = 0;↵
  ll mex = 0;↵
  for (ll i = 0;i<k;i++){↵
    if(mp[i]==0){↵
      cnt++;↵
    }↵
  }↵
↵
  cout << max(cnt,mp[k]) << endl;↵
}↵
int main() ↵
{↵
  ios::sync_with_stdio(false);↵
  cin.tie(0);↵
  ll t; cin >> t;↵
  while (t--){↵
    bruh();↵
  }↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
</spoiler>↵
↵
----↵
↵
<spoiler summary="Задача D:">↵
Полное решение:↵
↵
Допустим строка такая: ababaaba.  Давайте просимулируем процесс для все b, для наглядности.↵
↵
i = 2, нам нужно посчитать кол-во сдвигов слева и справа, т.к слева нет букв б, то берем справа.↵
↵
bab = bba = 1 сдвиг.↵
↵
bbaaab = bbbaaa &mdash; 3 сдвига.↵
↵
Заметим, что для каждого b от 0 до і, число сдвигов до і это кол-во букв а от j до і, где j<i.↵
↵
Также для каждого b от і до n, число сдвигов до n, это кол-во букв от і до j, где j>=i.↵
↵
Тут можно заметить, что для каждого i, s[i] == 'b', сумма сдвигов считается как↵
↵
(Lefta &mdash; Righta)*p[i]+((sump[n-1]-sump[i-1])-sump[i-1]), ↵
↵
где lefta &mdash; кол-во букв а от 0 до і-1, ↵
↵
а rigtha &mdash; кол-во букв а от і до n, p[i] &mdash; кол-во букв б от 0 до і-1. ↵
↵
Sump[i] &mdash; сумма всех p[i] таких индексов, что s[i]=='b'.↵
↵
Для буквы а делаем точно также, только уже с другими префиксами. Для большей наглядности можете просмотреть мой код.↵
↵
Сложность: O(n)↵
↵
<spoiler summary="Code:">↵
↵
~~~~~↵
#include <iostream>↵
#include <bits/stdc++.h>↵
#define ll long long ↵
#define pb push_back↵
#define f first↵
#define s second↵
#define all(x) x.begin(),x.end()↵
using namespace std;↵
bool check(ll k, string s, ll n){↵
 for (ll i = 0;i<n;i++){↵
    if(k<=0){↵
      break;↵
    }↵
    if(s[i-1]=='a' && s[i]=='b' && s[i+1]=='a' && i-1>=0 && i+1<n || ↵
    i==0 && s[i]=='b' && s[i+1] == 'a' && i+1<n){↵
      swap(s[i],s[i+1]);↵
      k--;↵
    }↵
  }↵
  for (ll i = 0;i<n;i++){↵
    if(s[i]=='b' && s[i+1]=='a' && i+1<n){↵
      return false;↵
    }↵
  }↵
  return true;↵
}↵
void bruh(){↵
  ll n; cin >> n;↵
  string s; cin >> s;↵
  ll cnt1 = 0;↵
  ll cnt2 = 0;↵
  ll l = 0;↵
  vector<ll> preff(n,0);↵
  for (ll i = 0;i<n;i++){↵
    if(s[i]=='a'){↵
      preff[i] = 1;↵
    }↵
  }↵
  vector<ll> p(n);↵
  p[0] = preff[0];↵
  for (ll i = 1;i<n;i++){↵
    p[i] = p[i-1]+preff[i];↵
  }↵
  vector<ll> pref(n,0);↵
  for (ll i = 0;i<n;i++){↵
    if(s[i]=='b'){↵
      pref[i] = 1;↵
    }↵
  }↵
  vector<ll> pp(n);↵
  pp[0] = pref[0];↵
  for (ll i = 1;i<n;i++){↵
    pp[i] = pp[i-1]+pref[i];↵
  }↵
  vector<ll> sump(n,0);↵
  vector<ll> sumpp(n,0);↵
  sump[0] = (s[0]=='b'? p[0]: 0);↵
  for (ll i = 1;i<n;i++){↵
    sump[i] = sump[i-1]+(s[i]=='b'? p[i]: 0);↵
  }↵
  sumpp[0] = (s[0]=='a'? pp[0]: 0);↵
  for (ll i = 1;i<n;i++){↵
    sumpp[i] = sumpp[i-1]+(s[i]=='a'? pp[i]: 0);↵
  }↵
  ll mx = 1e18;↵
  for (ll i = 0;i<n;i++){↵
    ll cnt = 0;↵
    if(s[i]=='b'){↵
      ll bas = (i==0? 0: pp[i-1]);↵
      ll bs = (i==0? 0: sump[i-1]);↵
      cnt = (bas-(pp[n-1]-bas))*p[i]+((sump[n-1]-bs)-bs);↵
    }else{↵
       ll bas = (i==0? 0: p[i-1]);↵
      ll bs = (i==0? 0: sumpp[i-1]);↵
      cnt = (bas-(p[n-1]-bas))*pp[i]+((sumpp[n-1]-bs)-bs);↵
    }↵
   ↵
    mx = min(mx,cnt);↵
  }↵
 // cout << cnt1 << " " << cnt2 << endl;↵
  cout << mx << endl;↵
//cout << ans << endl;↵
↵
  //cout << k << s << endl;↵
}↵
int main() ↵
{↵
  ios::sync_with_stdio(false);↵
  cin.tie(0);↵
  ll t; cin >> t;↵
  while (t--){↵
    bruh();↵
  }↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
</spoiler>↵
↵
----↵
↵
<spoiler summary="Задача Е:">↵
Полное решение:↵
↵
Сперва вспомним один из самых важных лайфхаков связанное с работой на отрезках, а именно:↵
↵
`Чтобы найти ответ для отрезка l; r, можно найти ответ для отрезка от 1 до r, и отнять от него ответ для отрезка от 1 до l-1.`↵
↵
Теперь как использовать это для этой задачи? Давайте найдем кол-во отрезков с различными числами <=k, на отрезке от l-1 до r, затем отнимем кол-во отрезков с различными числами <=k-1, на отрезке от l-1 до r. Это и будет нашим ответом для данной задачи. ↵
↵
P.S: Ответ мы можем находить с помощью двух указателей/ sliding window. Для большей ясности можете просмотреть мой код.↵
↵
Выведем наш ответ.↵
↵
Сложность: O(n)*4↵
↵
<spoiler summary="Code:">↵
↵
~~~~~↵
#include <iostream>↵
#include <bits/stdc++.h>↵
#define ll long long ↵
#define pb push_back↵
#define f first↵
#define s second↵
#define all(x) x.begin(),x.end()↵
using namespace std;↵
ll take(vector<ll> a, ll r, ll k){↵
  ll n = a.size();↵
  map<ll,ll> mp;↵
  ll ans = 0; ll l = 0;↵
  ll cnt = 0;↵
  for (ll i = 0;i<n;i++){↵
    mp[a[i]]++;↵
    if(mp[a[i]]==1){↵
      cnt++;↵
    }↵
    while (cnt>k){↵
      mp[a[l]]--;↵
      if(mp[a[l]]<=0){↵
        mp.erase(a[l]);↵
        cnt--;↵
      }↵
      l++;↵
    }↵
    if(i-r+1<l){↵
      ans+=(i-l+1);↵
    }else{↵
      ans+=(i-(i-r+1)+1);↵
    }↵
  }↵
  return ans;↵
}↵
void bruh(){↵
  ll n,k,l,r; cin >> n >> k >> l >> r;↵
  vector<ll> a(n);↵
  for (ll &x: a){↵
    cin >> x;↵
  }↵
  cout << ((take(a,r,k))-take(a,l-1,k))-(take(a,r,k-1)-take(a,l-1,k-1)) << endl;↵
}↵
int main() ↵
{↵
  ios::sync_with_stdio(false);↵
  cin.tie(0);↵
  ll t; cin >> t;↵
  while (t--){↵
    bruh();↵
  }↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
</spoiler>↵
↵

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
ru15 Russian Goddless 2025-09-30 23:50:26 0 (опубликовано)
ru14 Russian Goddless 2025-09-30 23:50:15 212
ru13 Russian Goddless 2025-09-30 23:49:22 8979
ru12 Russian Goddless 2025-09-30 23:44:43 24
ru11 Russian Goddless 2025-09-30 23:42:34 24
ru10 Russian Goddless 2025-09-30 23:41:20 37
ru9 Russian Goddless 2025-09-30 23:40:06 31
ru8 Russian Goddless 2025-09-30 23:39:05 6
ru7 Russian Goddless 2025-09-30 23:38:18 34
ru6 Russian Goddless 2025-09-30 23:37:00 12
ru5 Russian Goddless 2025-09-30 23:36:31 8
ru4 Russian Goddless 2025-09-30 23:35:58 5
ru3 Russian Goddless 2025-09-30 23:35:47 14
ru2 Russian Goddless 2025-09-30 23:35:28 395
ru1 Russian Goddless 2025-09-30 23:31:08 2863 Первая редакция (сохранено в черновиках)