Berilgan \(n\) ta elementdan iborat \(a_1, a_2, \dots, a_n\) massivdan shunday \((i, j)\) indekslar juftligini topish kerakki, bunda \(1 \le i < j \le n\) shart bajarilsin va ularning yig'indisi \((a_i + a_j)\) juft son bo'lsin. Jami shunday "Sehrli juftliklar" sonini topish talab etiladi.
Asosiy g'oya (Matematik yondashuv):
Ikkita sonning yig'indisi \((a_i + a_j)\) qachon juft son bo'ladi? Buni bilish uchun ularning juft yoki toqligini tekshirish kifoya:
Demak, yig'indi juft chiqishi uchun tanlab olingan ikkita sonning ikkalasi ham juft bo'lishi yoki ikkalasi ham toq bo'lishi kerak.
Algoritm:
1. Massivdagi barcha sonlarni qarab chiqamiz va ularning nechtasi juft, nechtasi toq ekanini sanab olamiz:
2. Juft sonlardan juftlik hosil qilish:
Agar massivda \(E\) ta juft son bo'lsa, ulardan ikkitasini tanlash usullari soni kombinatsealar formulasiga ko'ra \(E \times (E - 1) / 2\) ta bo'ladi.
3. Toq sonlardan juftlik hosil qilish:
Agar massivda \(O\) ta toq son bo'lsa, ulardan ikkitasini tanlash usullari soni \(O \times (O - 1) / 2\) ta bo'ladi.
4. Jami "Sehrli juftliklar" soni shu ikki qiymatning yig'indisiga teng:
\(\frac{E \times (E - 1)}{2} + \frac{O \times (O - 1)}{2}\)
Murakkablik:
Vaqt murakkabligi: \(O(n)\) — massivni bir marta to'liq ko'rib chiqib, juft va toq sonlar sanog'i topiladi. Bu \(n \le 2 \times10^5\) cheklovi uchun juda tez ishlaydi va vaqt chegarasiga bemalol ulguradi.
Xotira murakkabligi: \(O(1)\) yoki \(O(n)\) — massivni xotirada saqlash uchun (agar elementlarni birma-bir o'qib ketilsa, qo'shimcha massiv ham talab etilmaydi).
Bizga \(n\) ta kristallar energiyalari berilgan: \(a_1, a_2, \dots, a_n\), va yana maxfiy son \(k\). Shunday \((i, j)\) indekslar juftligini \((1 \le i < j \le n)\) topishimiz kerakki, ularning yig'indisi \(k\) ga qoldiqsiz bo'linsin, ya'ni \((a_i + a_j) \pmod k == 0\). Jami shunday juftliklar sonini chiqarish talab etiladi.
Asosiy g'oya (Matematik yondashuv / Modular Aritmetika):
Ikkita \(a_i\) va \(a_j\) sonlarining yig'indisi \(k\) ga bo'linishi uchun ularning \(k\) ga bo'lgandagi qoldiqlari yig'indisi \(k\) ga bo'linishi kerak. Boshqacha qilib aytganda:
\((a_i + a_j) \pmod k \equiv 0\) \( \iff\) \((a_i \pmod k + a_j \pmod k)\) \(\pmod k \equiv 0\)
Bu shartdan kelib chiqib ikki xil holatni ko'rishimiz mumkin:
Algoritm (Chastota massivi yoki Hash Map yordamida):
Murakkablik:
Vaqt murakkabligi: \(O(n)\) — massivni bir marta to'liq qarab chiqish va qoldiqlarni hisoblash kifoya. \(n \le 2 \cdot 10^5\) cheklovi uchun juda tez ishlaydi.
Xotira murakkabligi: \(O(k)\) yoki \(O(n)\) — qoldiqlar chastotasini saqlash uchun.
Bizga \(n \times m\) o'lchamli labirint berilgan. Boshlang'ich nuqta \((1, 1)\), oxirgi manzil esa \((n, m)\). Labirintda bo'sh kataklar ('.') va devorlar ('#') mavjud. Biz eng ko'pi bilan \(k\) ta devorni "buzib", oddiy bo'sh katakka aylantirgan holda \((1, 1)\) dan \((n, m)\) ga borish uchun ketadigan eng kam qadamlar sonini topishimiz kerak. Agar ilojsiz bo'lsa, \(-1\) chiqaramiz.
Asosiy g'oya (Shortest Path / BFS):
Bu turdagi eng qisqa yo'lni topish masalalarida BFS (Breadth-First Search - Eniga qidirish) algoritmidan foydalanamiz. Biroq, bu oddiy BFS emas, chunki bizda qo'shimcha resurs (\(k\) ta devor buzish imkoniyati) mavjud.
Holatni (state) quyidagicha belgilaymiz: \((r, c, \text{broken})\), bu yerda:
Cheklovlar kichik bo'lgani uchun (\(2 \le n, m \le 300\) va \(0 \le k \le \min(n \cdot m, 20)\)), holatlar soni unchalik katta emas.
Algoritm (0-1 BFS yoki Oddiy BFS + Visited massivi):
1. Navbat (Queue): BFS navbatiga boshlang'ich holatni qo'shamiz: \((1, 1, 0)\) — ya'ni \((1, 1)\) katakdamiz va hali \(0\) ta devor buzganmiz, qadamlar soni \(0\) ga teng.
2. Masofalar/Holatlar massivi (\(dist[r][c][broken]\)): Har bir katak uchun shu paytgacha sarflangan eng kam qadamlarni saqlab boramiz. Boshlang'ich qiymatlar cheksizlik (\(\infty\)) bilan to'ldiriladi.
3. Qadam tashlash:
4. Optimallashtirish: Har safar yangi holatga o'tganda qadamlar soni kamroq bo'lsagina uni navbatga qo'shamiz va dist massivini yangilaymiz.
5. \((n, m)\) katakiga yetib kelganimizdagi eng birinchi topilgan qadamlar soni eng qisqa yo'l bo'ladi (chunki BFS qadamma-qadam kengayib boradi). Agar oxirigacha borib bo'lmasa, \(-1\) chiqaramiz.
Murakkablik:
Vaqt murakkabligi: \(O(n \times m \times k)\) — har bir katak va har bir mumkin bo'lgan buzilgan devorlar soni holati uchun navbatdan bir marta o'tiladi. \(300 \times 300 \times 20 \approx 1.8 \times 10^6\) operatsiyani tashkil qiladi va vaqt chegarasiga bemalol ulguradi.
Xotira murakkabligi: \(O(n \times m \times k)\) — dist massivi va navbat uchun sarflanadigan xotira.
Bu masalada berilgan massivni tartibini buzmagan holda \(m\) ta ketma-ket bo'lakka bo'lishimiz va har bir bo'lak yig'indilarining eng kattasini (maksimal qismini) imkon qadar kichik qilishimiz talab etiladi.
Asosiy g'oya (Binary Search on Answer):
Massiv elementlari va o'lchami katta bo'lgani uchun (\(\le 2 \times 10^5\)), to'g'ridan-to'g'ri qidirib chiqish vaqt chegarasiga ulgurmaydi. Shuning uchun javobning o'zini ikkilik qidiruv orqali topamiz.
1. Qidiruv chegaralari (low va high):
2. Ochko'zlik (Greedy) yondashuvi:
Ikkilik qidiruv orqali o'rtadagi qiymatni (\(mid\)) eng katta ruxsat etilgan limit deb olamiz. Keyin massivni chapdan o'ngga qarab yig'ib chiqamiz:
Murakkablik
Ikkilik qidiruv taxminan \(O(\log(\text{sum}(a)))\) marta takrorlanadi.
Har bir tekshirish (greedy o'tish) \(O(n)\) vaqt oladi.
Umumiy murakkablik: \(O(n \times \log(\text{sum}(a)))\).