Реши на C++ за O(n): У Little X есть n различных ц...

Creado el: 24 de febrero de 2025

Respondido usando O1 por Chat01

Pregunta

Реши на C++ за O(n):
У Little X есть n различных целых чисел: p1, p2, ..., pn. Он хочет так разделить все числа на два множества, A и B, чтобы выполнялись условия:

Если число x принадлежит множеству A, то число a - x также должно принадлежать множеству A.
Если число x принадлежит множеству B, то число b - x также должно принадлежать множеству B.
Помогите Little X разделить числа на два множества или определите, что это невозможно.

Входные данные
В первой строке записано три целых числа через пробел n, a, b (1 ≤ n ≤ 105; 1 ≤ a, b ≤ 109). В следующей строке записано n различных целых чисел через пробел p1, p2, ..., pn (1 ≤ pi ≤ 109).

Выходные данные
Если способ разделения чисел на два множества существует, то выведите "YES" в первой строке. Затем выведите n целых чисел: b1, b2, ..., bn (bi равняется либо 0, либо 1), описывающих разделение. Если bi равняется 0, то pi принадлежит множеству A, в противном случае оно принадлежит множеству B.

Если это невозможно, выведите "NO" (без кавычек).

Примеры
Входные данныеСкопировать
4 5 9
2 3 4 5
Выходные данныеСкопировать
YES
0 0 1 1
Входные данныеСкопировать
3 3 4
1 2 4
Выходные данныеСкопировать
NO

Pensamiento

Understanding the constraints

I'm thinking through partitioning n distinct integers into sets A and B, ensuring if x is in A, then a-x must also be in A, and similarly for B.

Simplifying the challenge

I'm determining if integers can be partitioned into sets A and B, ensuring x and a-x stay in the same set, aiming for an efficient O(n) solution.

Aligning set constraints

It's becoming clear that aligning set constraints for integers in A and B while ensuring each integer is mapped uniquely to A or B is crucial for resolving conflicts.

Assigning integers logically

I'm using a hash map to assign integers to sets A or B, ensuring x and a-x are in the same set, aiming for a unique, conflict-free partition.

Aligning constraints

I’m ensuring x and a-x are always together in the same set, simplifying the partitioning of integers into sets A and B by adhering strictly to the constraints.

Parsing constraints

I'm digging into the constraints, finding a direct implication only for integers in set A. There's no stated relationship between x and a-x for set B.

Mapping relationships

I'm beginning to see each integer establishes connections to other pairs, forming a graph. This setup highlights constraints on valid set partitions.

Introducing constraints

I'm reframing the problem by assigning colors to each integer, ensuring constraints dictate that for any integer x in set A, a-x should share the same color, and similarly for set B.

Ensuring valid pairings

By confirming x and a-x are either both in set A or both in set B, and not mixing sets A and B, it ensures compliance with constraints.

Mapping valid pairs

I'm identifying valid color combinations for (x, a-x) and (x, b-x). The pair (0,1) for (x, a-x) and (1,0) for (x, b-x) are disallowed due to specific constraints.

Mapping valid color assignments

I'm listing valid color combos for each pair (x, a-x) and (x, b-x), ensuring each set avoids restricted pairs like (0,1) and (1,0).

Piecing together implications

I’m reversing constraints into logical implications like if x=0 then a-x=0, translating them into boolean variables for each vertex's color, aligning with common 2-SAT methods.

Evaluating complexity

I’m comparing 2-SAT methods, examining constraints like not allowing (0,1) pairs for (x, a-x). This seems feasible, but I’ll assess simpler alternatives to streamline the process.

Defining color constraints

I'm forming the color function c(x) to ensure pairs (x, a-x) and (x, b-x) adhere to constraints, such as c(x) ≤ c(a-x) and c(x) ≤ c(b-x), aligning with the given rules.

Clarifying constraints

I’m refining the constraints, confirming that for pairs (x, a-x) and (x, b-x), c(x) should be less than or equal to both c(a-x) and c(b-x). This ensures adherence to the given rules.

Refining constraints

I’m tweaking constraints to simplify the logical expression: ensuring c(x) ≤ c(a-x) for pairs (x, a-x) and c(b-x) ≥ c(x) for pairs (x, b-x). This ensures clarity and adherence to the rules.

Mapping out constraints

I'm aligning constraints: for pairs (x, a-x), c(x) should be ≤ c(a-x); for pairs (x, b-x), c(x) should be ≥ c(b-x), ensuring consistency.

Assessing consistency

I'm thinking through whether it's feasible to assign 0 or 1 to each x in S that meets the inequalities, and whether these constraints might cause a contradiction through cyclic chaining.

Constructing directed edges

I’m mapping directed edges to link each x with constraints: c(x) ≤ c(a-x) and c(b-x) ≤ c(x). This approach helps visualize relationships and maintain logical consistency.

Mapping cycle implications

I’m mapping out the impact of cycles enforced by non-strict inequalities. These cycles ensure all nodes within must share the same value, facilitating a consistent coloring scheme.

Piecing together SCCs

It's becoming clear that each strongly connected component (SCC) in the directed graph must share the same color. Arranging these SCCs by partial order constraints might simplify the coloring problem.

Ensuring consistency

I’m thinking through maintaining consistent coloring in the condensation graph by confirming paths between vertices adhere to the non-strict inequality, ensuring all vertices meet the coloring constraints.

Assigning values

OK, let me see. Each strongly connected component (SCC) in the directed acyclic graph needs a consistent value (0 or 1) so that all edges (SCC1 -> SCC2) are satisfied, without violating the non-strict inequality.

Mapping topological layering

I’m pulling together how to color the directed acyclic graph (DAG) so edges flow from lower to higher color or stay constant, ensuring a valid 2-coloring without forced conditions.

Assessing potential extensions

I’m examining if extending the partial order constraints could ensure a valid 2-coloring. It seems the non-strict constraints allow for colors to satisfy c(SCC1) <= c(SCC2) <= c(SCC3).

Evaluating constraints

I'm pulling together the constraints in the example to see if they align with our logic, especially when analysis reveals that nothing in the set prevents a solution.

Mapping out constraints

I'm examining the constraints and figuring out how they impact values for nodes 1, 2, and 4, ensuring the logic aligns with the problem's expected outcome.

Pulling together the constraints

I’m figuring out that if node 1 or 2 is in A, node 1’s color forces node 2’s to match. This leaves them either both 0 or both 1.

Ensuring uniformity

I'm piecing together that for nodes 1 and 2 to maintain the "if x is in A, a-x is in A" condition, their colors must match and can either both be 0 or 1.

Evaluating color schemes

Checking valid color assignments for nodes 1, 2, and 4, I ensure they meet constraints for sets A and B, though initial checks suggest the problem's expected outcome is unachievable.

Aligning the solution

I’m thinking through the constraints and found that the assignment for c(1), c(2), and c(4) is logically valid. This discrepancy hints at a potential oversight in the example's expected outcome.

Piecing together constraints

OK, let me see. Let's dissect the example input and output, ensuring all constraints are met. Despite finding a valid assignment, there's a contradiction with the problem's requirements.

Piecing it together

Considering a subtle detail: for every x in A, a-x needs to be in set S too. This crucial factor might have been overlooked.

Ensure alignment

OK, let me see. If x is in set A, then a-x needs to be present in A too, only separating integers from a specific set without including b-x.

Ensuring set integrity

If x belongs to set A, then a-x must also be there. This requirement is pivotal for the set's coherence and needs careful consideration.

Crafting set rules

OK, let's map out the constraints: if x is in set A, then a-x must be in set S and A; similarly, for set B. This ensures valid placement.

Confirming constraints

Ensuring x's placement in A or B by checking if a-x or b-x is in set S. This approach maintains constraints and guarantees valid placement.

Figuring it out

If both a-x and b-x aren't in S, x can't go in either set. Meaning, x has to go in set A.

Placing elements

OK, let me see. For x=2, I’m figuring out it can go into either A or B without causing a contradiction, thanks to the self-referencing logic of the constraint.

Figuring out solutions

First, if 1 is in A, then 2 must be too. Then, I'm noting 4 can't go in either A or B, so no valid partition is available.

Filling in available space

I’m piecing together the solution by working through each element, ensuring consistency with constraints. It’s interesting to confirm that 2 and 3 fit within the limits.

Finalizing the partition

I’m mapping out the allocation by placing 4 and 5 in B, which forces 4 and 5 to be together, resulting in the consistent partition: A={2,3}, B={4,5}.

Piecing together constraints

I’m establishing that each element x in S must be placed consistently in A or B based on specific constraints, ensuring all elements are used and consistent with the conditions.

Clarifying set rules

I’m figuring out that for each x, it either pairs with a-x in A or B, or both are left out. This ensures all elements are used appropriately.

Mapping connections

I'm thinking through x's placement by linking it with partnerA = a-x and partnerB = b-x in S. Ensuring both or neither are in A or B is crucial.

Formulating a solution

I'm mapping out a method to use BFS or union-find for grouping elements in one set, ensuring all constraints are met efficiently.

Crafting a strategy

I'm assembling a plan to enumerate possible sets for each x and give them constraints, making sure the set and its necessary pairings consistently align for A and B.

Connecting elements

Hmm, thinking through x and a-x, and similarly x and b-x, ensuring each "connected component" is placed consistently in either A or B, but not both.

Mapping out choices

If x is bound to A, a-x must stay in A. I’m thinking about how to handle linked elements to ensure constraints are consistently met.

Mapping progress

Strategizing to ensure x and a-x stay in A, and x and b-x avoid conflicts. Using BFS or union-find, I'm aiming for a consistent assignment for all elements.

Mapping the approach

First, I read inputs and set constraints. Then, I use BFS to assign elements consistently to A or B, ensuring all constraints are met for a valid configuration.

Ensuring consistency

Working through assigning the remaining elements to A or B, ensuring no contradictions. This leads us to a consistent configuration, completing the solution.

Ensuring consistency

Choosing 0 or 1 for x, verifying no conflicts, and progressing through connected components to maintain a consistent assignment for all elements. This approach helps identify and resolve contradictions early on.

Piecing it together

I’m working on the time complexity, ensuring each element is processed once for constraints. If no contradiction appears, I’ll finalize the color assignment, leading to a solution.

Evaluating constraints

Starting with a=3, b=4. I identify forced assignments and contradictions, showing progress in reasoning down to a clear conclusion. This is the best way to handle the situation.

Mapping constraints

I'm walking through forced assignments: 2->0, 3->0, 4->1, 5->1. Next, I'll push these into the queue and propagate constraints using BFS to resolve contradictions.

Confirming consistency

OK, let me see. I’m confirming the final color assignments for each element using BFS. No contradictions appear, and the solution works perfectly, confirming the BFS approach effectively.

Piecing together constraints

If an element has two possible values, it will be color 0 after BFS. The implementation might involve another BFS pass or a single pass with color set to 0.

Validating constraints

I'm piecing together constraints for each element with a bitmask. If a contradiction arises, the algorithm indicates no valid colors exist, ensuring each element has a suitable color assignment.

Spotting contradictions

I'm digging into color mask contradictions for all elements. If an element can’t have a valid color, I either retry or set the element to a suitable color using BFS.

Evaluating backtracking

I'm considering if backtracking might be necessary since choosing color 0 can cause immediate contradictions in the BFS, and the single ISO non-assignment pass might not suffice.

Trying another way

Thinking through a Function named attempt_color(i, c) to address contradictions. This method prioritizes BFS simplicity and weighs various approaches for consistency and efficiency.

Confirming color assignment

Assigning 0 to x consistently avoids contradictions, as the problem constraints don't necessitate backtracking. The logic remains intact throughout the process.

Final edge cases

I'm finalizing the BFS logic by setting color_mask[i]=1 for elements with color_mask[i]=3 and ensuring no contradictions. If contradictions appear, color_mask[i] is set to 2.

Reasoned for 4m 40s

Respuesta

Анализ задачи

Даны nn различных целых чисел p1,p2,,pnp_1, p_2, \dots, p_n. Нужно разбить их все на два подмножества AA и BB так, чтобы выполнялись условия:

  1. Если xAx \in A, то axa - x (если оно вообще есть среди данных nn чисел) тоже должно попасть в AA.
  2. Если xBx \in B, то bxb - x (если оно есть среди данных nn чисел) тоже должно попасть в BB.

Причём каждое из данных чисел должно быть либо в AA, либо в BB (никаких «неиспользованных» не остаётся).

Однако из формулировки в задаче часто пропускается критическая деталь:

«Если xAx \in A, то axa-x должно принадлежать множеству AA»
означает не только «если axa-x уже среди наших nn чисел, то оно тоже обязано быть в AA», но и косвенно накладывает запрет класть xx в AA, если axa-x не встречается в списке из nn чисел. Ведь мы можем раскладывать только данные nn чисел по множествам, а «требовать» в AA число, которого в исходном наборе нет, невозможно.

Иными словами:

  • Число xx можно поместить в AA только если axa-x тоже содержится среди p1,,pnp_1,\dots,p_n. И при этом тогда автоматически axa-x тоже идёт в AA.
  • Число xx можно поместить в BB только если bxb-x тоже содержится среди p1,,pnp_1,\dots,p_n. И при этом тогда автоматически bxb-x тоже в BB.

Если для какого-то xx оба варианта (положить в AA или в BB) невозможны, значит задачу решить нельзя. Либо же при попытках удовлетворить все «цепочки» условий возникнет противоречие.


Примеры из условия

text
n=4, a=5, b=9 p = [2, 3, 4, 5]
  • Посмотрим, кто может попасть в AA:

    • 2A2\in A возможно, только если 52=35 - 2 = 3 тоже есть среди чисел. Да, 33 в списке есть, значит «теоретически» 22 может пойти в AA, и тогда 33 обязана быть там же.
    • 3A3\in A возможно, только если 53=25 - 3 = 2 тоже в списке. Да, значит 22 и 33 либо вместе в AA, либо нет.
    • 4A4\in A возможно, только если 54=15 - 4 = 1 есть среди наших чисел. Но 11 нет в списке {2,3,4,5}\{2,3,4,5\}. Значит нельзя класть 44 в AA.
    • 5A5\in A возможно, только если 55=05 - 5 = 0 есть среди чисел. Но 00 нет в списке. Значит нельзя класть 55 в AA.
  • Посмотрим, кто может попасть в BB:

    • 2B2\in B возможно, только если 92=79 - 2 = 7 в списке. Но 77 нет, значит 22 в BB положить нельзя.
    • 3B3\in B возможно, только если 93=69 - 3 = 6 в списке. 66 нет, значит тоже нельзя.
    • 4B4\in B возможно, только если 94=59 - 4 = 5 есть среди чисел. Да, 55 есть. Значит 44 может быть в BB, тогда 55 тоже обязательно в BB.
    • 5B5\in B возможно, только если 95=49 - 5 = 4 в списке. Да, 44 есть, значит 44 и 55 либо вместе в BB, либо нет.

Получается, что:

  • {2,3}\{2,3\} должны попасть в AA (иначе их вообще «девать некуда»).
  • {4,5}\{4,5\} должны попасть в BB.

Это действительно согласовано и даёт разбиение:

A={2,3},B={4,5}.A = \{2,3\},\quad B = \{4,5\}.

В ответе выводят:

text
YES 0 0 1 1

(если нумерация p идёт как [2,3,4,5], то 0 означает «в A», 1 — «в B»).

text
n=3, a=3, b=4 p = [1, 2, 4]
  • Для 11:

    • Можно ли в AA? Нужно, чтобы 31=23 - 1 = 2 был в списке. Он есть, так что теоретически 11 может пойти в AA при условии, что вместе с ним и 22 тоже попадёт в AA.
    • Можно ли в BB? Нужно, чтобы 41=34 - 1 = 3 был в списке. Но 33 нет, значит в BB положить 11 нельзя.

    Следовательно, 11 обязан оказаться в AA.

  • Для 22:

    • Может ли быть в AA? Тогда надо, чтобы 32=13 - 2 = 1 был в списке — да, 11 есть, более того, мы уже «поняли», что 11 уходит в AA. Значит 22 может тоже быть в AA (и тогда это согласуется с тем, что 11 в AA).
    • Может ли быть в BB? Тогда надо, чтобы 42=24 - 2 = 2 был в списке (он и есть, это «само на себя»). Формально это условие не противоречит: 22 в BB «требует» 22 в BB. Это замкнуто, и само по себе не мешает.

    На первый взгляд 22 мог бы пойти куда угодно, но поскольку 11 уже обязан в AA, а «11 в AA     \implies 31=23-1=2 тоже в AA», то это заставляет 22 тоже быть в AA.

  • Для 44:

    • Может ли быть в AA? Нужно, чтобы 34=13 - 4 = -1 был в списке, а 1-1 явно нет. Значит 44 невозможно положить в AA.
    • Может ли быть в BB? Нужно, чтобы 44=04 - 4 = 0 был в списке, а 00 нет. Значит 44 невозможно положить и в BB.

Итого, 44 не получается положить ни в AA, ни в BB. Поэтому задача не имеет решения, ответ «NO».


Итоговая проверка «можно ли распределить»

  1. Для каждого числа xx из входного набора проверяем, какие варианты (0 = «A», 1 = «B») вообще возможны.

    • «xx может быть в AA» тогда и только тогда, когда (ax)(a-x) тоже присутствует среди наших nn чисел.
    • «xx может быть в BB» тогда и только тогда, когда (bx)(b-x) присутствует среди наших nn чисел.
      Если для какого-то xx оба варианта отпали, сразу «NO».
  2. Далее нужно учесть, что если (по ходу решения) вдруг «xx точно пошёл в AA», это автоматически заставляет (ax)(a-x) тоже быть в AA, и так далее каскадом. Аналогично для BB. Если эти каскадные требования вступают в противоречие, то решения нет.

  3. Если для каких-то чисел выбор не жёстко фиксирован (им можно и в AA, и в BB), мы можем выбрать любой из вариантов, но с учётом связей «в паре» (при выборе xAx\in A обязательно «axa-x в AA» и т.п.). Если каскад не даёт противоречий, то решение существует.

Для реализации за O(n)O(n) удобно воспользоваться следующей схемой:

  • Сначала подготовим:

    • Сохраним все pip_i в массив p.
    • Построим хеш-таблицу/словарь indexOf, чтобы быстро по значению находить индекс в p.
    • Заведём массив possible[i] (например, в виде битовой маски), который говорит, куда может пойти pip_i. Изначально possible[i] = 0b11 (т.е. оба варианта разрешены).
    • Если (api)(a - p_i) не в наборе, то убираем «бит» 0b01 (то есть «в AA» нельзя). Если (bpi)(b - p_i) не в наборе, убираем «бит» 0b10 (то есть «в BB» нельзя). Если после этого possible[i] == 0, немедленно выводим «NO» и завершаемся.
  • Далее фиксируем «жёстко определившиеся» элементы, для которых осталась ровно одна возможность (possible[i] == 0b01 или possible[i] == 0b10). Складируем их в очередь и обрабатываем по принципу «широкого поиска»:

    • Извлекаем элемент xx с его уже определённой меткой (допустим, xx пошёл в AA). Тогда необходимо, чтобы (ax)(a-x) тоже пошёл в AA. Это значит, что у (ax)(a-x) мы должны сохранять только бит «можно в AA» и выкинуть «можно в BB». Если у него это приводит к «нельзя никуда» — противоречие, «NO». Если у него раньше было «оба можно», а теперь стало «только AA», то он тоже стал «жёстко определённым», добавляем его в очередь. Аналогично для xBx\in B.
  • По ходу этого процесса либо выйдет конфликт, либо мы «сжав» все связи получим подмножество элементов, у которых осталось по одному варианту. Те элементы, у которых и в конце остались оба варианта AA или BB, мы можем свободно (без противоречий) выбрать как AA или BB. Обычно достаточно «пробежаться» и всем им присвоить, скажем, AA (если оно у них действительно в possible[i]), сделав аналогичную финальную «протяжку» по связям. В этой задаче не нужно искать все способы, достаточно любого корректного.

  • Если в итоге все pip_i получили допустимые цвета без конфликта, печатаем «YES» и раскладку (0/1). Если по пути — «NO», выводим «NO».

Этот метод укладывается в O(n)O(n)O(nlogn)O(n \log n) (все связи — максимум по 2 «партнёра» на каждый xx: axa-x и bxb-x).


Решение на C++

Ниже приведён вариант кода, реализующий описанную идею.

cpp
#include <bits/stdc++.h> using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n; long long a, b; cin >> n >> a >> b; vector<long long> p(n); for(int i=0; i<n; i++){ cin >> p[i]; } // Сохраним в словарь "значение -> индекс" // Чтобы быстро находить, где лежит a-x или b-x unordered_map<long long,int> indexOf; indexOf.reserve(n); indexOf.max_load_factor(0.7f); for(int i=0; i<n; i++){ indexOf[p[i]] = i; } // possible[i] будет битовой маской: // 0b01 (единица) - можно ли i-й элемент положить в A, // 0b10 (двойка) - можно ли i-й элемент положить в B. // Изначально ставим 0b11 (оба варианта), // потом будем вычеркивать невозможное. vector<int> possible(n, 0b11); // Предварительно обрежем те варианты, где a-x или b-x не существует в наборе // Если a-x не найдём, убираем бит "A" // Если b-x не найдём, убираем бит "B" for(int i=0; i<n; i++){ long long x = p[i]; // Проверка на возможность "x в A" // Нужно, чтобы (a - x) был в словаре if(!indexOf.count(a - x)){ // Невозможно x в A possible[i] &= ~0b01; // вычёркиваем бит A } // Проверка на возможность "x в B" // Нужно, чтобы (b - x) был в словаре if(!indexOf.count(b - x)){ // Невозможно x в B possible[i] &= ~0b10; // вычёркиваем бит B } // Если оказалось, что вариантов нет, сразу NO if(possible[i] == 0){ cout << "NO\n"; return 0; } } // Очередь для "жёстко зафиксированных" элементов // Будем хранить пары (индекс, color), где color=0 для A, color=1 для B. queue<pair<int,int>> q; // Если у кого-то один бит остался, сразу добавляем в очередь auto pushForced = [&](int i){ // Если possible[i] == 1 (бит 0b01) => color=0 // Если possible[i] == 2 (бит 0b10) => color=1 // Если 3 - оба варианта, пока не трогаем if(possible[i] == 1){ q.push({i,0}); } else if(possible[i] == 2){ q.push({i,1}); } }; for(int i=0; i<n; i++){ if(possible[i] == 1 || possible[i] == 2){ pushForced(i); } } // Функция, которая "заставляет" элемент i идти в цвет c (0 или 1), // и сразу обрезает вариативность. Если конфликт - вернёт false. auto fixColor = [&](int i, int c){ // c=0 => бит A=0b01, c=1 => бит B=0b10 int bit = (1 << c); // Если у i уже не включает bit, значит конфликт if((possible[i] & bit) == 0){ return false; } // Иначе "обрезаем" всё, кроме нужного бита if(possible[i] != bit){ possible[i] = bit; // Добавим в очередь, чтобы отработать связанные q.push({i, c}); } return true; }; // Выполним обход в ширину, отрабатывая "жёсткие" приписки while(!q.empty()){ auto [i, c] = q.front(); q.pop(); long long x = p[i]; if(c == 0){ // x пошёл в A => (a - x) тоже должен пойти в A long long y = a - x; int j = indexOf[y]; // по условию есть // Заставляем j быть тоже в A if(!fixColor(j, 0)){ cout << "NO\n"; return 0; } } else { // x пошёл в B => (b - x) тоже должен пойти в B long long y = b - x; int j = indexOf[y]; if(!fixColor(j, 1)){ cout << "NO\n"; return 0; } } } // Если ещё остались элементы possible[i] == 3 (оба варианта), // мы можем свободно выбрать им, например, A (color=0) – // и если это где-то далее вызовет фиксации, тоже прогоняем. for(int i=0; i<n; i++){ if(possible[i] == 3){ // Попробуем зафиксировать в A (c=0), // это точно не даст противоречий, // ведь если "можно и то, и другое", // то выбирать A – законно. // Но важно запустить fixColor, чтобы цепочки дозаполнились. if(!fixColor(i, 0)){ // если вдруг конфликт (что маловероятно, // т.к. мы проверили "possible[i] == 3"), // тогда была бы опция fixColor(i,1). // Но с учётом логики — не должно здесь быть конфликта. cout << "NO\n"; return 0; } // Запустим цикл обработки, пока все цепочки не улягутся while(!q.empty()){ auto [ii, cc] = q.front(); q.pop(); long long xx = p[ii]; if(cc == 0){ long long yy = a - xx; int jj = indexOf[yy]; if(!fixColor(jj,0)){ cout << "NO\n"; return 0; } } else { long long yy = b - xx; int jj = indexOf[yy]; if(!fixColor(jj,1)){ cout << "NO\n"; return 0; } } } } } // Если дошли сюда — решение есть. cout << "YES\n"; // Выведем раскладку в том же порядке, что и входные p[i]. // У нас: possible[i] будет 1 (значит "A") или 2 (значит "B"). // Нужно вывести 0 для A, 1 для B: for(int i=0; i<n; i++){ if(possible[i] == 1){ cout << 0 << " "; // A } else { cout << 1 << " "; // B } } cout << "\n"; return 0; }

Пояснения к коду:

  • Мы сначала сохраняем в possible[i] все допустимые варианты для pip_i.

    • Если (api)(a - p_i) нет в словаре, убираем возможность кластm pip_i в AA.
    • Если (bpi)(b - p_i) нет в словаре, убираем возможность кластm pip_i в BB.
    • Если после этого ничего не остаётся, сразу «NO».
  • Далее все элементы, у которых осталась ровно одна возможность (т.е. possible[i] == 1 или possible[i] == 2), мы складываем в очередь q как жёстко зафиксированные.

  • В цикле while(!q.empty()) берём «зафиксированный» элемент xx. Если он зафиксирован в AA, то и (ax)(a-x) обязан быть в AA. Если у (ax)(a-x) изначально была возможность (B) — её теперь нужно исключить. Если окажется, что у (ax)(a-x) вообще больше нет вариантов, значит противоречие. Если у (ax)(a-x) после «обрезания» остался ровно один вариант, мы тоже добавляем (ax)(a-x) в очередь и так рекурсивно/каскадно. Аналогично с BB.

  • После полного «пропихивания» очереди может остаться часть элементов, у которых possible[i] == 3, т.е. они по-прежнему «могут и в AA, и в BB». Для них мы делаем выбор (скажем, попробуем «в AA»), и если это порождает новые фиксации, опять пойдёт очередь. Если возникнет противоречие, теоретически можно было бы попробовать «в BB», но в данной задаче (как показывает анализ) конфликт в таком месте не возникает, поскольку possible[i] == 3 означает, что (api)(a-p_i) и (bpi)(b-p_i) оба лежат в наборе, и цепочки таких «двусторонних» вершин не приведут к тупику — мы всегда можем выбрать любую сторону, и всё согласуется (если не возникало обязательств от соседей).

  • Если в итоге конфликтов не обнаружилось, мы печатаем «YES» и конечную раскладку.

Таким образом за один-полтора прохода (плюс очередь) всё раскладывается за O(n)O(n). Если где-то по пути ловим противоречие — «NO».

Это ровно соответствует примеру, где во втором тесте ( p={1,2,4},a=3,b=4p=\{1,2,4\}, a=3, b=4 ) моментально выяснится, что для элемента 44 изначально possible[..]==0 (оба бита выкидываются), и мы печатаем «NO». А в первом тесте ( p={2,3,4,5},a=5,b=9p=\{2,3,4,5\}, a=5, b=9 ) получаем ровное распределение.


Итог:

  • Идея основная — учесть, что «xx в AA» возможно лишь при наличии axa-x в нашем наборе. Аналогично для BB.
  • Затем «склеивать»/«протаскивать» эти требования через очередь или через «систему взаимных ограничений».
  • Если в каком-то месте вариантов не остаётся, ответ «NO». Иначе «YES» + восстановленная раскладка.

Compartir este Q&A