A. Dominolar
Shunchaki masalada aytilgan ishni qilish yetarli. Agar \(N \ge 28\) bo'lsa javob “Enough”, aks holda javob \(28-N\).

n = int(input())
if n >= 28:
	print("Enough")
else:
	print(28 - n)

 

B. Satrlarni tenglash
Har bir \(i (0 \le i < N)\) uchun \(A_i\) va \(B_i\) ni tekshiramiz. Agar ulardan biri unli, boshqasi unsiz bo'lsa javobni oshirib qo'yamiz.

a = input()
b = input()

vowels = "aeiouy"
answer = 0
for i in range(len(a)):
    x = a[i] in vowels # 0 - undosh, 1 - unli
    y = b[i] in vowels
    if x != y:
        answer += 1

print(answer)

 

C. Introvert Komiljon
Barcha bo'sh o'rinlarni qarab chiqaylik. Barcha bo'sh bo'lmagan o'rindiqlar uchun, Komiljon o'tirgan o'rindiqqa eng yaqinini topamiz.
Complexity: \(O(N^2)\). Shuningdek, masalani \(O(N)\)da ham yechish mumkin. 

n = int(input())
s = input()

def dist(a, b):
    return min(abs(a - b), n - abs(a - b))

ans = [-1, 0]
for i in range(n):
    if s[i] == '.':
        cur = n
        for j in range(n):
            if s[j] == '#':
                cur = min(cur, dist(i, j))
        if ans[-1] < cur:
            ans = [i + 1, cur]
print(ans[0])

 

D. Masalalar tuzuvchi kengash (editorial uchun Dilyorbekka rahmat)
Boshliq agar \(X\)ta masala tuzgan bo'lsa, unda bundan oz masala tuzgan boshliqlar bizga qiziq emas, aksincha undan ko'p masala tuzgan boshliqlar hammasi ba'zi masalalarini o'chirishi kerak bo'ladi. Agar boshqa boshliq \(Y\)ta masala tuzgan bo'lsa, \(Y-X\)ta masalani o'chirishga to'g'ri keladi. Shundan kelib chiqib, \(B\) bu hozirgi boshliqdan ko'proq masala tuzganlar massivi bo'lsa, va uzunligi \(M\) bo'lsa, unda rad etish kerak bo'lgan masalalar soni: \(\sum_1^m(B_i - x)\) bo'ladi. Bu summani har bir kishi uchun hisoblab chiqish \(O(N^2)\) yechim beradi, lekin bu sekinlik qiladi:

for i in range(n):
  current_cost = 0
  for j in range(n):
    if a[j] >= a[i]:
      current_cost += a[j] - a[i]

Endi tasavvur qilaylik, bizga berilgan \(A\) array kamaymaslik tartibda berildi. Unda hozirgi boshliqdan ko'proq tuzgan boshliqlar faqat o'ng tomonda bo'lishi mumkin. Yuqoridagi summaga yaxshiroq e'tibor bersak, uni soddalashtirish mumkin. \(X\) konstanta, demak bo'lgani uchun tashqariga chiqarsa bo'ladi:
\(\sum_1^m (B_i - x) = \sum_1^m B_i - m * x\) 
Complexity: \(O(N\log{N})\).

Python:

n = int(input())
a = list(map(int, input().split()))

for i in range(n):
  a[i] = (a[i], i)  # boshlang'ich indexni saqlab qo'yamiz
a.sort()

suff = [0] * n
suff[n - 1] = a[n - 1][0]
for i in range(n - 2, -1, -1):
	suff[i] = suff[i+1] + a[i][0]

answer = [0] * n

for i in range(n):
	m = n - i
	current_cost = suff[i]
	current_cost -= m * a[i][0]
	answer[a[i][1]] = current_cost

print(*answer)

C++:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int n;
    cin >> n;
    vector<pair<int, int>> arr(n);
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        arr[i] = {x, i};
    }
    sort(arr.begin(), arr.end());

    vector<ll> suff(n);
    suff[n - 1] = arr[n - 1].first;
    for (int i = n - 2; i >= 0; i--) {
        suff[i] = suff[i + 1] + arr[i].first;
    }

    vector<ll> ans(n);
    for (int i = 0; i < n; i++) {
        ll m = n - i;
        ans[arr[i].second] = suff[i] - (ll)m * arr[i].first;
    }
    for (int i = 0; i < n; i++) {
        cout << ans[i] << ' ';
    }
    cout << endl;

    return 0;
}

 

E. K-th subarray sum
Masalani biroz o'zgartiraylik. \(X\) berilgan bo'lsin, \(A_l + ... + A_r \le X\) bajariladigan \([l, r]\) juftliklar sonini topa olamizmi? Agar buni qila olsak, shunchaki juftliklar soni \(\ge K\) bo'ladigan minimal \(X\)ni topsak yetarli. Shunda masalani ikkilik qidiruv (binary search) algoritmi bilan yechish mumkin.
Har bir \(l\) indeks uchun \(A_l + ... + A_r \le X\) bo'ladigan \(r\) indekslarni qanday topish mumkin?
Muhim hossa: barcha elementlar nomanfiy bo'lgani uchun, \(r\) oshgan holatda yig'indi ham oshadi. Demak, maksimal \(r\)ni boshqa binary search yordamida topish mumkin. Bunda sizga prefix massivlar yordam berishi mumkin.
Complexity: \(O(N \cdot \log{\rm{ANS}} \cdot \log{N})\), bunda \(\log{\rm{ANS}}\) javobni qidirish uchun, \(\log{N}\) esa maksimal \(r\)ni qidirish uchun.
P.S. Ikkinchi binary search o'rniga "ikkita ko'rsatkich" (two pointers) algoritmini qo'llansa, yechim asimptotikasi \(O(N \log{\rm{ANS}})\) ga tushadi. Biroq Accepted olish uchun bu optimizatsiya shart emas edi.

C++ (binary search):

#include <bits/stdc++.h>

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);

    int n; long long k;
    cin >> n >> k;

    vector<long long> p(n + 1);
    for (int i = 1; i <= n; i++){
        int x;
        cin >> x;
        p[i] = p[i - 1] + x;
    }

    long long l = 0, r = 2e14;
    while (l <= r){
        long long val = (l + r) / 2;

        long long cnt = 0;
        for (int i = 1; i <= n; i++){
            int j = upper_bound(p.begin(), p.end(), p[i - 1] + val) - p.begin();
            cnt += j - i;
        }

        if (cnt >= k){
            r = val - 1;
        } else {
            l = val + 1;
        }

    }

    cout << r + 1 << endl;

    return 0;
}

C++ (two pointers):

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n; cin >> n;
    long long k; cin >> k;

    vector<long long> a(n);
    for(int i = 0; i < n; ++i) cin >> a[i];
    
    auto check = [&](long long x) -> bool {
        long long cnt = 0, s = 0;

        int l = 0;
        for(int r = 0; r < n; ++r) {
            s += a[r];
            while(s > x) {
                s -= a[l];
                l++;
            }
            cnt += r - l + 1;
        }

        return (cnt >= k);
    };

    long long l = -1, r = 2e18;
    while (r - l > 1) {
        long long mid = (l + r) / 2;
        if( check(mid) ) r = mid;
        else l = mid;
    }

    cout << r << endl;
}