[Решења задатака] 2025/2026 Окружно

Мајсторија

Аутор: Марко Миленковић

Текст: и тест примери: Марко Миленковић

Анализа решења: Марко Миленковић

Тестирање: Алекса Милисављевић

NM \leq 20

У овом подзадатку можемо проверити за сваку конфигурацију матрице да ли задовољава услове. Односно, за свако поље матрице имамо две опције - или је нула или је јединица у њему. Укупно онда имамо 2^{NM} опција. Испробавањем сваке од тих опција можемо да утврдимо да ли постоји валидна.

Сложеност овог приступа је \mathcal{O}(NM2^{NM}).

NM \leq 30

Из услова да број јединица у реду i мора бити дељив бројем i, можемо да закључимо да неки редови морају да буду прилично пуни. На пример, последњи ред и последња колона морају бити скроз попуљени. Уз ову констатацију можемо смањити број могућности у претходном подзадатку.

NM \leq 45

Можемо приметити да нема много опција које нам дају NM \leq 45. За овај подзадатак можемо да израчунамо на свом рачунару (користећи претходне оптимизације) и то сачувамо у меморију.

Без додатних ограничења

Лако примећујемо да уколико је N \neq M, решење не постоји. Зашто? Нека важи да има више редова него колона (симетрично резоновање ради у супротном случају). Онда последњни ред мора да има барем N јединица (да би испунио дељивост, а сетимо се, не сме да има нула јединица по тексту задатка). Међутим, како има M < N колона, то је немогуће. Дакле, на даље резонујемо само случај N = M.

Постоји више одговарајућих конструкција за решавање овог задатка. Чини се да је најпростија да се јединице ставе на споредној дијагонали матрице и на сва поља испод ње. Формални услов би био, попунимо јединицама сва поља за која важи i + j >= N+1. Онда ће ред/колона i имати тачно i јединица.

Временска сложеност је O(NM).

Хари Потер

Аутор: Марко Миленковић

Текст и тест примери: Алекса Милисављевић

Тестирање: Алекса Данић и Марко Миленковић

Анализа решења: Ања Дожић

Подзадатак 1: n\leq10

Приметимо да Харију никада неће бити оптимално да направи два везана потеза која неће уклонити дементорe. Дакле, највећи број потеза које Хари може да направи у овом подзадатку је 2n. Како је n мало, можемо испробати све могуће секвенце које задовољавају услове задатка (има их 3\cdot2^{2n}) и видети у којој ће број дементора које Хари може да уклони бити највећи.

Временска сложеност: O(2^{2n})

Подзадатак 2: x_i<0, за 1\leq i\leq n

Како у овом подзадатку не постоје дементори северно од Харија, њему је увек безбедно да направи корак напред (тј. корак ка северу). Приметимо да ће му у овом случају оптимална стратегија бити да на смену понавља акције 2 и 3, тј. да прво уклони најближег јужног дементора и затим се помери корак северно и то понавља док не уклони све дементоре.

Хари ће у овом подзадатку сигурно моћи да уклони све дементоре јер након што на почетку уклони најближег себи и затим се помери корак напред, најближе што је први следећи најближи дементор могао да приђе је тачно један корак иза Харија, па ће Хари моћи да га уклони у наредном потезу.

Временска сложеност: O(n)

Подзадатак 3: x_i>0, за 1\leq i\leq n

У овом подзадатку, сви дементори ће се налазити северно од Харија, те њему никада неће бити оптимално да направи корак напред и приближи им се. Одатле закључујемо да ће му у овом случају оптимална стратегија бити да на смену понавља акције 1 и 2, тј. да прво уклони најближег северног дементора и затим баци чин ка југу “у празно”.

За разлику од претходног подзадатка, овде не можемо гарантовати да ће Хари моћи да уклони све дементоре. Прво ћемо сортирати низ дементора. Приметимо да Хари i-тог дементора може да уклони након тачно 2i-1 потеза, дакле пошто се Хари не креће, довољно је да се i-ти дементор налази на неком пољу које је мање од 2i-1 и он ће га сустићи. Решење добијамо након што прођемо кроз низ дементора проверавајући да ли неки од њих може да сустигне Харија. Након што наиђемо на првог који може да га сустигне, исписујемо број дементора које је Хари до тог тренутка уклонио и раније описану секвенцу потеза. Ако ни један не може да га сустигне, исписујемо број дементора и секвенцу.

Временска сложеност: O(n\cdot\log n)

Подзадатак 4: |x_i| је парно за 1\leq i\leq n

Слично као и у претходном подзадатку, ако Хари на смену понавља акције 1 и 2, он ће i-тог дементора на северу уклонити након тачно 2i-1 потеза, док ће j-тог дементора на југу уклонити након тачно 2j потеза. Ова стратегија нам гарантује да ће Хари моћи да уклони све дементоре у овом подзадатку, јер се они налазе само на парним пољима, тј. i-ти дементор на северу никада неће бити на пољу ближем од 2i, као што ни j-ти дементор на југу никада неће бити на пољу ближем од 2j.

Временска сложеност: O(n)

Подзадатак 5: Цело решење

Приметимо сада да је Харију оптимално да направи корак напред једино када је на то приморан тј. када је већ бацио чин ка југу и има једног дементора тачно иза себе. У сваком другом случају, бацање чини ка северу ће му се више исплатити јер тиме уклања дементора северно ако постоји и сигуран је да га ниједан дементор неће стићи.

Дакле, мораћемо да проверимо две могућности: када је Харијево прво бацање чини ка северу и када је Харијево прво бацање чини ка југу (у претходном подзадатку нам то није било важно јер су сви дементори били на парним пољима што нам је остављало довољно простора за одабир стране прве чини). Чуваћемо два сортирана низа координата, позитивне и негативне, и паралелно проверавати да ли неки дементор може да сустигне Харија ако баца наизменично чини ка северу па ка југу (тј. ка југу па ка северу у другом случају). Приметимо да не морамо да апдејтујемо цео низ позиција дементора после сваког потеза, већ да једноставно можемо добити тренутну позицију жељеног дементора тако што на њу додамо или одузмемо број потеза које смо направили у зависности од тога да ли је дементро јужно или северно од Харија. Ако се испостави да га дементор који је јужно од њега стиже, следећи потез ће му уместо чини ка северу бити померање у напред и затим поново чин ка југу. Тај број потеза апдејтујемо и настављамо да проверавамо док Хари не уклони све дементоре или док га дементор испред њега не сустигне јер од њега нема начин да побегне.

Временска сложеност: O(n\cdot\log n)

Абакус 2

Аутор: Марко Миленковић

Текст: и тест примери: Марко Миленковић

Анализа решења: Марко Миленковић

Тестирање: Милош Милутиновић

N \leq 1.000.000

За најмања ограничења, где је N до милион, можемо применити директну симулацију (“брут форс”). Потребно је проћи кроз сваки природни број i од 1 до n, израчунати производ његових цифара и тај резултат убацити у структуру података која чува само јединствене вредности (на пример std::set у C+±у). Производ цифара се рачуна једноставним издвајањем последње цифре (операција % 10) и целобројним дељењем (операција / 10) све док број не постане нула. На крају, решење је величина скупа у који смо смештали производе. Временска сложеност овог приступа је O(N \cdot \log_{10} N), што се за N=10^6 извршава довољно брзо.

N \leq 10^{12}

Директна итерација је преспора. Приметимо да редослед цифара не утиче на њихов производ. На пример, бројеви 124, 421 и 214 сви дају исти производ 8. То значи да је довољно посматрати само комбинације цифара, а не све пермутације. Можемо користити рекурзивну претрагу да генеришемо низове цифара које су неопадајуће. Тиме осигуравамо да сваку комбинацију цифара обрадимо само једном. За сваки генерисани низ цифара, најмањи број који се од њих може саставити добија се надовезивањем тих цифара у растућем поретку. Ако је тај најмањи број мањи или једнак задатом N, његов производ цифара убацујемо у скуп решења.

Без додатних ограничења

Можемо приметити да се производ цифара састоји од производа простих бројева 2,3,5,7, јер се сваки број може представити преко просте факторизације, а прости бројеви после 7 не чини цифре (двоцифрени су).

Рачунаћемо који је најмањи природан број чији је производ цифара једнак 2^a3^b5^c7^d, а онда итераритати по свим могућностима бројева a,b,c,d. Све ове бројеве чувамо у сортираној листи.

Да бисмо направили што мањи број, гледамо да испоштујемо два правила:

  1. Пакујемо просте чиниоце у што веће бројеве - дакле 2^3 у 8, 3^2 у 9, а ако нам остану нека двојка и тројка после тога, пакујемо их у 6. Ако након тога остану двојке, пакујемо их у четворку. Може се проверити да су ово једине могућности.

  2. Сортирамо цифре растуће да бисмо остварили што мањи број.

Додатно имамо специјалне случајеве за 1 и 10, јер они први производе бројеве 1 и 0. Даље итерирамо по четворци a,b,c,d и притом пазимо да не пређемо границу великих бројева у C+±у.

Све радимо пре икаквог уноса и онда можемо бинарном претрагом да пронађемо за свако N који је први број који је мањи од N.

Xормутације 2

Аутор: Милош Милутиновић

Текст и тест примери: Mилош Милутиновић

Анализа решења: Милош Милутиновић

Tестирање: Алекса Милисављевић

Решење када N, Q \leq 10

Можемо за сваки подниз изабрати које елементе желимо да користимо у низу, и за добијени низ проверимо да ли је он добар користећи грубу силу. Сложеност O(Q N^2 2^N).

Решење када су сви елементи степени двојке

Приметимо да ако узмемо два иста елемента за њих очигледно важи X = X \ and \ X > X \ xor \ X = 0. Такође уколико узмемо два различита елемента за њих важи 0 = X \ and \ Y < X \ xor \ Y = X + Y. Тиме се добија да је довољно наћи елемент који се највише пута појављује. То се може урадити тако што се сваки члан низа замени као A_i = log_2{A_i}. Како је сада 0 \leq A_i \leq 30, мoжемо направити префиксне суме по броју појављивања сваког елемента и одговорити упите лако. Сложеност O((N + Q) log_2{A}).

Решење када N, Q \leq 5000

Уколико изаберемо два елемента чији су највећи битови различити, тада услов очигледно неће важити, јер and неће садржати тај бит док xor хоће. Слично уколико су им највећи битови исти, and ће садржати тај бит док xor неће. Тиме добијамо услов да је низ добар уколико сваки пар бројева има исти највећи бит. Сада сваки члан низа заменимо његовим највећим битом. За сваки упит потребно је одговорити са највећим бројем појављивања неког елемента у поднизу. То можемо лако урадити грубом силом. Сложеност O(N Q).

Главно решење

Комбиноваћемо претходне две идеје. Након замене сваког елемента са његовим највећим битом важиће 0 \leq A_i \leq 30. Сада можемо направити префиксне суме као у подзадатку где је сваки елемент степен двојке и на исти начин одговорити упите. Сложеност О((N + Q) log_2{A}).

Васа, скупљач ауре

Аутор: Алекса Данић

Текст и тест примери: Алекса Милисављевић

Анализа решења: Алекса Данић

Тестирање: Марко Трајковић

Решење када је N \leq 20

У овом подзадатку имамо времена да за сваки подниз фиксирамо скуп индекса на којима се коефицијент повећава, и израчунамо Васину ауру за сваки од тих скупова.

Временска сложеност: O(n^2{k \choose x})

Важна формула за све наредне подзадатке

Посматрајмо конкретан подниз [l,r] дужине k. Нека је ind_c први индекс на ком је Васа узео елемент са коефицијентом c (у случају да је Васа узео елемент p_r са коефицијентом x-1, нека је ind_x=r+1). Нека је sum(a,b)=p_a+p_{a+1}+\dots+p_{b-1}+p_b, (sum(a,b)=0 за a>b). Приметимо да је укупна Васина аура након проласка кроз подниз једнака:

\sum_{i=1}^x sum(ind_i,r)

Ово је збир x суфиксних сума на поднизу [l,r]. Када бисмо за свако p_i израчунали у колико различитих суфиксних сума се тај елемент налази, видели бисмо да је то управо исти број као коефицијент испред тог елемента који је Васа изабрао. Ево примера за лакше разумевање формуле на низу [1,2,3,4,5,6], где су изабрани коефицијенти [1,1,2,2,3,3]:

1 \cdot 1 + 1 \cdot 2 + 2 \cdot 3 + 2 \cdot 4 + 3 \cdot 5 + 3 \cdot 6 = sum(1,6)+sum(3,6)+sum(5,6)
sum(1,6)=1+2+3+4+5+6, sum(3,6)=3+4+5+6, sum(5,6)=5+6

Видимо, на пример, да се број 2 појављује само једном, у суфиксној суми sum(1,6), а да се број 5 појављује у све три суфиксне суме. Такође, коефицијент испред 2 је 1, а коефицијент испред 5 је 3.

Уведимо и ознаку suff_i=sum(i,n). Тада је sum(a,b)=suff_a-suff_{b+1}.

Решење када је p_i \geq 0

Исплати се узети сваки елемент са што већим коефицијентом, па ће Васа повећавати коефицијент сваки пут кад може. Решење за конкретан подниз [l,r], \space r-l+1=k је 1p_l+2p_{l+1}+\dots+xp_{l+x-1}+xp_{l+x}+xp_{l+x+1}+\dots+xp_r=\sum_{i=l}^{l+x-1}sum(i,r)=\sum_{i=l}^{l+x-1}(suff_i-suff_{r+1})=(\sum_{i=l}^{l+x-1}suff_i)-x \cdot suff_{r+1}. Сума коју смо добили у овој формули је сума x узастопних елемената низа suff, коју можемо брзо наћи уколико прекалкулишемо низ префиксних сума над низом suff.
Дакле, нека је P_i=suff_1+suff_2+\dots+suff_{i-1}+suff_i, P_0=0. Решење за интервал [l,r] дужине k је једнако

P_{l+x-1}-P_{l-1}-x \cdot suff_{r+1}

Временска сложеност: O(n)

Решење када је n \leq 300

Спорије имплементације наредног подзадатка дају поене за овај подзадатак.

Решење када је n \leq 3000

Посматрајмо конкретан подниз [l,r] дужине k. Решење за овај подниз је

\sum_{i=1}^x sum(ind_i,r)=\sum_{i=1}^{x}(suff_{ind_i}-suff_{r+1})=(\sum_{i=1}^{x}suff_{ind_i})-x \cdot suff_{r+1}

Потребно је да изаберемо низ ind тако да је вредност наведеног израза што већа. Приметимо да је x \cdot suff_{r+1} константа, па је потребно максимизовати \sum_{i=1}^{x}suff_{ind_i}, или речима, треба нам збир суфиксне суме која почиње на индексу l (јер је ind_1=l), и x-1 највећих суфиксних сума које почињу на индексима између l+1 и r+1. Можемо сортирати све ове суфиксне суме, након чега је лако наћи збир највећих x-1.

Временска сложеност: O(n^2 \log n) - довољно за максималан број поена на овом подзадатку

Уколико бисмо сортирали све суфиксне суме пре фиксирања подниза, и за сваку памтили који индекс јој одговара, након фиксирања подниза бисмо у O(n) могли да издвојимо само суфиксне суме којима одговара индекс из интервала [l+1,r+1], и то у сортираном поретку. Овим приступом избегавамо сортирање за сваки подниз.

Временска сложеност: O(n^2)

Решење када је x = 2

У претходном подзадатку смо видели да је потребно да нађемо збир x-1 највећих suff_i за i \in [l+1,r+1].
Дакле, у овом подзадатку нам треба максимум сваког интервала дужине k низа suff. Користићемо технику sliding window.

Један начин је да користимо структуру података попут std::multiset из стандардне библиотекте програмског језика C++. Ова структура података, између осталог, подржава операције додавања, брисања, и дохватања највећег елемента, све у временској сложености O(\log n), и одржава елементе у уређеном поретку (сортиране по неком критеријуму).

Рецимо да смо нашли максимум на интервалу [l,r], и да су нам у multiset-у сви елементи на том интервалу. Када у multiset додамо suff_{r+1}, а из њега избацимо suff_l, можемо наћи максимум на интервалу [l+1,r+1].
Почињемо од интервала [1,k], и понављајући наведени поступак можемо ефикасно наћи решења за сваки интервал дужине k.

Временска сложеност: O(n \log n)

Постоји и решење у временској сложености O(n) које користи ред са два краја - std::deque, али није неопходно за максималан број поена на овом подзадатку.

Решење за 100 бодова

У решењу за 100 бодова нам треба збир x-1 максимума сваког интервала дужине k низа suff, али у ефикаснијој сложености него у подзадатку n \leq 3000.
Као у подзадатку x \leq 2, користићемо технику sliding window, и структуру података std::set.

Рецимо да смо нашли збир x-1 максимума на интервалу [l,r]. Назовимо тај збир S. Нека је all set чији су елементи сви уређени парови (suff_i, i) за i \in [l,r]. Нека је largest set чији су елементи уређени парови (suff_i, i) за i \in [l,r], али само они за које је suff_i међу x-1 максимума интервала [l,r] (уколико су x-ти и x-1-ви максимум једнаки, међу елементима те вредности узимамо произвољне, тако да је |largest|=x-1).

Да бисмо прешли на интервал [l+1,r+1], потребно је додати елемент suff_{r+1} и избацити елемент suff_l из наших структура, и адекватно ажурирати S, all и largest.

Хајде најпре да видимо како правилно додати елемент suff_{r+1}.
За почетак додајемо уређени пар (suff_{r+1},r+1) у оба set-а и повећавамо S за suff_{r+1}, а потом бришемо најмањи елемент setlargest и смањујемо S за вредност тог елемента.
Након ових операција all чува све вредности на интервалу [l,r+1], largest чува x-1 максимума тог интервала, а S њихову суму.

Потребно је још обрисати елемент suff_l.
Бришемо уређени пар (suff_{l},l) из all. Такође га бришемо и из largest, али само ако се он налази у том set-у.
Ако се (suff_{l},l) није налазио у largest, завршили смо - all чува све елементе интервала [l+1,r+1], largest чува x-1 максимума међу њима, а S њихову суму.
Други случај је да се (suff_{l},l) налазио у largest. У том случају смо остали без једног од x-1 максимума, па смањујемо S за suff_l и морамо наћи x-1-ви максимум преосталих елемената. Ми знамо x-2-ги максимум, то је најмањи елемент из largest, а x-1-ви максимум се налази непосредно пре њега у all, па се он може наћи помоћу std::set::lower_bound(). Након што нађемо нови x-1-ви максимум, додајемо га у largest и повећавамо S за његову вредност.

Након свих операција смо успешно прешли са интервала [l,r] на интервал [l+1,r+1].
Као у претходном подзадатку, крећемо од [1,k] и понављањем наведеног поступка тражимо решење за све интервале дужине k.

Временска сложеност: O(n \log n)

Дуња, делиоци и xor

Аутор: Немања Мајски

Текст и тест примери: Немања Мајски

Анализа решења: Немања Мајски

Тестирање: Алекса Милисављевић

n \leq 1.000

За сваки број x \in \{1, 2, \ldots, n\} ћемо да прођемо петљом од 1 до x како би нашли све његове делиоце и њихов xor. Те резултате памтимо у низу. Сада да би нашли одговор за било који делилац можемо само да га прочитамо из тог низа.

Времеска сложеност је O(n^2), а меморијска O(n).

n \leq 10^5

Рецимо да тражимо све делиоце неког броја x. Приметимо да ако број d дели број x, онда и број \frac{x}{d} дели број x. Такође, за сваки делилац d броја x важи d \le \sqrt{x} или \frac{x}{d} \le \sqrt{x}. Самим тиме петљу којом тражимо делиоце можемо пустити да итерира само до \sqrt{x}, док делиоце веће од \sqrt{x} налазимо дељењем броја x са делиоцима мањим од \sqrt{x}.

Времеска сложеност је O(n \sqrt{n}), а меморијска O(n).

n \leq 10^7

Приметимо да је број x делилац бројева x, 2x, 3x \ldots. Тако да како би нашли делиоце свих бројева од 1 до n можемо ићи редом кроз бројеве i \in \{1, 2, \ldots, n\}. Када смо на броју i, ми га додамо бројевима i, 2i, 3i \ldots као делиоца.

Такође, нама није важно који су делиоци неког броја, већ само колики је њихов xor. Зато је идеја да прво направимо низ res где ће на почетку бити res_i = 0 за свако 1 \le i \le n. Затим идемо редом кроз бројеве 1, 2, \ldots, n. Када смо на броју i, ми променимо res_j := res_j\ \text{xor}\ i за свако j \in \{i, 2i, 3i\ldots\}.

На први поглед изгледа као да је сложеност описаног алгоритма доста велика и да није довољно брз. Али, приметимо да за i=x ми ћемо направити највише \frac{n}{x} корака. То значи да ми укупно правимо највише \frac{n}{1}+\frac{n}{2}+\frac{n}{3}+\ldots+ \frac{n}{n} корака. Може да доказати да је \frac{1}{1} +\frac{1}{2} +\frac{1}{3} +\ldots + \frac{1}{n} = O(log\ n) кад n \to \infty, па је самим тиме временска сложеност O(n\ log\ n).

Меморијска сложеност је O(n).

n \leq 10^9

Приметимо да бројеви углавном имају много мање делиоца него колика је њихова вредност. Односно, сви бројеви који су мањи или једнаки 10^9 имају највише 1344 делиоца. Односно, то што је n \le 10^9 имплицира и огранићење k \le 1344.

Нека је d делилац броја n. Очигледно је да су и сви његови делоци такође делиоци броја n. Тако да како би нашли за неки од делиоца броја n, нека је то број d, који су његови делиоци, можемо проћи кроз листу свих делиоца броја n и проверити да ли деле број d.

Временска сложеност је O(k^2). Меморијска сложеност је O(k).

Без додатних ограничења

Нека је P број простих фактора броја n. Комисијско решење је у сложености O(kP). Постоје и спорија решења која вреде 100 поена, али предлажемо да пробате смислити решење у наведеној сложености.

Сваком делиоцу ћемо придружити низ res_i, такав да је res_i = \text{xor\_delilaca}(i). Да би могли приступити том низу у O(1), користићемо хеш мапе ( std::unordered_map у c++ ). Ограничења су таква да су се смели користити и асоцијативни низови ( std::map у c++ ).

Размислимо шта бисмо урадили да је n степен неког простог броја броја p. Како можемо у O(k) да решимо овај задатак?

Приметимо да важи за свако d | n да је res_d = d\ \text{xor}\ res_{\frac{d}{p}}, са додатним ограничењем да је res_1 = 1. Па да бисмо нашли вредности низа res за све делиоце броја n, можемо применити нешто слично префиксним сумама.

Сада претпоставимо да број n има P простих делилаца, p_1, p_2, \ldots, p_P. Нека је d делилац броја n и нека су његови прости фактори q_1, q_2, \ldots, q_Q. Из претходног примера би претпоставили да важи $$res_d = d\ \text{xor}\ res_{\frac{d}{q_1}} \ \text{xor}\ res_{\frac{d}{q_2}}$$ Али то није случај. Узмимо на пример број 6. Приметимо да res_6 = 6 \neq 7 = 6 \ \text{xor}\ 3\ \text{xor}\ 2 = 6\ \text{xor}\ res_2 \ \text{xor}\ res_3. Проблем је што се број 1 рачуна и као делилац броја 2, и као делилац броја 3, па је два пута урачунат.

Морамо другачије дефинисати низ res. Нека је res_{i,j} xor свих делилаца броја i који су облика i \cdot p_1^{\alpha_1} \cdot p_2^{\alpha_2} \cdot \ldots \cdot p_j^{\alpha_j}, где -\infty < \alpha_i \le 0. Односно, свих делилаца броја i који се могу добити тако што се број i неки број пута подели неким од бројева p_1, p_2, \ldots, p_j. Основни случајеви су res_{i,0} = i и res_{1,j} = 1. За остале вредности пратимо следећа правила:

  • Ако је \text{nzd}(i, p_j) = 1, онда је res_{i,j} = res_{i, j-1}.
  • Ако је \text{nzd}(i, p_j) = p_j, онда је res_{i,j} = res_{i,j-1}\ \text{xor}\ res_{\frac{i}{p_j},j-1}.
  • Иначе је res_{i,j} = res_{i,j-1}\ \text{xor}\ res_{\frac{i}{p_j},j}.

Овај прелаз се може наћи преко префисне суме слично као у примеру где је n степен простог броја. Такође, није нам потребно да заправо памтимо другу димензију низа res. Погледати комисијску имплементацију за додатне детаље.

Временска сложеност је O(kp), док је меморијска сложеност O(k).