Москва только хорошеет с годами. Так в году ...

Creato il: 2 settembre 2025

Risposto usando GPT-5 Thinking da Chat01

Domanda

Москва только хорошеет с годами. Так в

году вдоль серой ветки построили бесконечное количество зданий, которые нумеруются всеми возможными целыми числами.

Хоть у студентов ВШЭ и большая стипендия, но вместе с бесконечным количеством домов в Москве появился бесконечный спрос на жилище. Поэтому студентам приходится снимать квартиры группами.

Всего есть
групп студентов, причем известно, что
-я группа состоит из
студентов, которые решили поселиться в доме
. Из-за бытовых особенностей каждая группа состоит из студентов одного пола
, для юношей выполняется
, а для девушек —
.

Каждая группа студентов также регулярно выходит на прогулки, в ходе которых посещает участки серой ветки из какой-то окрестности их дома, не отходя от своего дома на расстояние большее, чем
. Из-за этих прогулок студенты иногда знакомятся друг с другом. Будем считать, что студенты из группы
знакомы со студентами из группы
, если выполнено
.

Каждый студент-юноша решил найти себе ровно одну онлайн-подружку, которая тоже учится во ВШЭ и с которой он на данный момент не знаком. Студенты волнуются, что если у одной девушки появится сразу два онлайн-друга, то у нее не хватит времени на учебу, и она отчислится, поэтому они хотят избегать такой ситуации.

Вам требуется определить, смогут ли все студенты-юноши найти себе по онлайн-подружке так, чтобы никакая пара юношей не подружилась с одной и той же девушкой.

Обратите внимание, что если нет ни одного юноши, который учится в ВШЭ, то ответ на задачу «Yes».

Формат входных данных
В первой строке вам дано число
— количество тестовых наборов. Следующие строки содержат описания тестовых наборов.

В первой строке каждого набора содержится целое число
(
).

Во второй строке указаны числа
(
).

В третьей строке указаны числа
(
).

В четвертой строке указаны числа
(
).

В пятой строке указаны числа
(
).

Гарантируется, что сумма
по всем тестовым наборам не превосходит
.

Формат результата
Для каждого теста в отдельной строке выведите «Yes» (без кавычек), если каждый из юношей может найти себе по уникальной онлайн-подружке, и «No» (без кавычек) иначе.

Pensiero

Proposing algorithm and solution

The web search didn’t turn up the exact problem, so I’ll propose a general solution in Russian. First, we’ll create intervals for boys and girls and ensure that the total number of girls is greater than or equal to the total number of boys. Then, we apply Hall’s condition to determine possible pairings based on interval overlaps and sides.

Clarifying condition

Okay, I’m working through the condition where for any point tt, the number of boys whose intervals intersect tt should be less than or equal to the total number of girls minus those whose intervals intersect tt. The condition simplifies to S(t)GtotalS(t) \leq G_{\text{total}}, suggesting that the total number of girls must be sufficient for matching at every point. I think this might be both necessary and sufficient, but I need to verify.

Revisiting the condition

For the worst-case scenario where many boys cluster over a segment, they can only pair with girls whose intervals don't intersect this point. So, I need to ensure that the number of boys intersecting point tt is less than or equal to the number of girls whose intervals don't intersect tt. This leads to the condition that for each point tt, the total number of students covering tt cannot exceed the total number of girls.

Reconsidering the condition

Hmm, the condition might seem too strict. If there are many girls at tt, the left-hand side of the equation could become large, even if there are many girls overall. However, girls at tt cannot be matched with boys at tt. This constraint might still form a useful starting point. It feels like the condition could help construct a matching, potentially utilizing max-flow at specific points.

Thought for 2m 42s

Risposta

Похоже, что у вас «интервальная» задача про знакомства на серой ветке. Удобно свести её к отрезкам:

  • Для каждой группы ii зададим отрезок прогулок
    [Li,Ri]=[xidi,  xi+di][L_i, R_i] = [x_i-d_i,\; x_i+d_i] и «вес» aia_i — сколько студентов в группе.
  • Группа ii и группа jj «знакомы» тогда и только тогда, когда их отрезки пересекаются:
    [Li,Ri][Lj,Rj][L_i, R_i] \cap [L_j, R_j] \neq \varnothing (это эквивалентно xixjdi+dj|x_i-x_j|\le d_i+d_j).
  • Юноша может выбрать онлайн-подружку только среди девушек, чей отрезок с ним не пересекается.

Значит, каждый юноша со своим отрезком может «матчиться» только с девушками, чьи отрезки лежат целиком слева от его LL или целиком справа от его RR. Это типичная задача про паросочетание в «интервальном» двудольном графе, и у неё есть простой критерий выполнимости, который удобно проверять «линией сканирования».

Критерий (необходим и достаточен)

Обозначим:

  • GtotG_{\text{tot}} — общее число девушек (сумма aia_i по всем женским группам).
  • BtotB_{\text{tot}} — общее число юношей.

Рассмотрим произвольную точку tt на оси домов и величины:

  • B(t)B(t) — сколько юношей (по сумме aia_i) имеют отрезок, покрывающий tt.
  • G(t)G(t) — сколько девушек (по сумме aia_i) имеют отрезок, покрывающий tt.

Юноши, чьи отрезки покрывают tt, не могут выбрать девушек, чьи отрезки тоже покрывают tt. Для них доступны только девушки, чьи отрезки целиком вне точки tt, т.е. GtotG(t)G_{\text{tot}}-G(t).

Чтобы всех юношей можно было разобрать по уникальным девушкам, нужно и достаточно:

  1. GtotBtotG_{\text{tot}} \ge B_{\text{tot}} (девушек не меньше, чем юношей), и
  2. Для всех tt: B(t)GtotG(t)\quad B(t) \le G_{\text{tot}} - G(t),
    эквивалентно B(t)+G(t)Gtot\quad B(t) + G(t) \le G_{\text{tot}}.

Интуиция: «узкие места» возникают только в точках разбиения прямой — внутри каждого «промежутка» между соседними концами отрезков набор покрывающих групп не меняется, и именно там выполняются (или рушатся) условия Холла. Поэтому достаточно проверить условие в этих точках.

Как проверить за O(nlogn)O(n \log n)

Сделаем «сканлайн» по событиям начала/конца отрезков отдельно суммируя мальчиков и девочек.

  1. Для каждой группы ii:

    • Li=xidiL_i = x_i - d_i, Ri=xi+diR_i = x_i + d_i.
    • Если это юноши: добавьте событие (Li,+ai)(L_i, +a_i) к BB, (Ri,ai)(R_i, -a_i) к BB.
    • Если девушки: аналогично к GG.
  2. Соберите все события (две мультисортированные ленты или одна с пометкой пола).
    Упорядочьте по координате; при одинаковой координате сначала применяйте «закрывающие» события (a)(-a), потом «открывающие» (+a)(+a) — так внутри полуинтервала [L,R][L, R] покрытие считается верно.

  3. Пробегая слева направо, поддерживайте текущие суммы BcurB_{\text{cur}} и GcurG_{\text{cur}}.
    В каждом «стабильном» промежутке между соседними событиями проверяйте:

    Bcur+GcurGtot.B_{\text{cur}} + G_{\text{cur}} \le G_{\text{tot}}.

    Если нарушено — ответ «No».

  4. Отдельно перед сканлайном проверьте GtotBtotG_{\text{tot}} \ge B_{\text{tot}}. Если нет — «No».
    Если юношей нет вовсе (Btot=0B_{\text{tot}}=0) — по условию сразу «Yes».

Все суммы держите в 64-битных целых.

Почему этого достаточно

  • Необходимость: в точке tt всем юношам, чьи отрезки покрывают tt, доступны только GtotG(t)G_{\text{tot}}-G(t) девушек; значит B(t)B(t) не может превышать это число.
  • Достаточность: в интервалах граф такого вида Hall’а сводится к проверкам на «точечных разрезах». Если они пройдены и девушек в сумме хватает, всегда существует паросочетание, которое можно построить жадно (параллельно «сжирая» доступных слева/справа) или через поток на упорядоченной сети, но сканлайн-критерий уже гарантирует существование.

Формат входа/выхода и реализация

В вашем описании 5 строк на тест:

  • nn — число групп;
  • массив aia_i — численности;
  • массив xix_i — дома;
  • массив sis_i — пол (например, 'M'/'F' или 0/1 — используйте то, что дано);
  • массив did_i — радиусы прогулок.

Дальше для каждого теста печатаем Yes/No.

Ниже — лаконичный каркас на C++17 (без ввода-вывода украшательств), который реализует ровно эту проверку. Вам останется только подогнать парсинг пола под конкретный формат ('M'/'F', 0/1, B/G и т.п.):

cpp
#include <bits/stdc++.h> using namespace std; using int64 = long long; struct Ev { long long x; long long db; // delta boys long long dg; // delta girls int type; // 0 = close(-), 1 = open(+), to break ties bool operator<(const Ev& other) const { if (x != other.x) return x < other.x; return type < other.type; // close before open } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; if (!(cin >> T)) return 0; while (T--) { int n; cin >> n; vector<long long> a(n), x(n), d(n); for (int i=0;i<n;++i) cin >> a[i]; for (int i=0;i<n;++i) cin >> x[i]; vector<char> s(n); for (int i=0;i<n;++i) { string t; cin >> t; s[i] = t[0]; // адаптируйте при необходимости } for (int i=0;i<n;++i) cin >> d[i]; long long Btot = 0, Gtot = 0; vector<Ev> evs; evs.reserve(2*n); for (int i=0;i<n;++i) { long long L = x[i] - d[i]; long long R = x[i] + d[i]; bool boy = (s[i]=='M' || s[i]=='m' || s[i]=='B' || s[i]=='b' || s[i]=='0'); if (boy) { Btot += a[i]; evs.push_back({L, +a[i], 0, 1}); // open evs.push_back({R, -a[i], 0, 0}); // close } else { Gtot += a[i]; evs.push_back({L, 0, +a[i], 1}); evs.push_back({R, 0, -a[i], 0}); } } if (Btot == 0) { cout << "Yes\n"; continue; } if (Gtot < Btot) { cout << "No\n"; continue; } sort(evs.begin(), evs.end()); long long Bcur = 0, Gcur = 0; bool ok = true; for (size_t i=0;i<evs.size();) { long long xcoord = evs[i].x; // применяем все события в этой точке по порядку (close перед open) while (i < evs.size() && evs[i].x == xcoord && evs[i].type == 0) { Bcur += evs[i].db; Gcur += evs[i].dg; ++i; } // между текущей точкой и следующей точкой покрытие постоянно. // Проверяем условие в «промежутке», если такой имеется. long long nextx = (i < evs.size() ? evs[i].x : xcoord); if (nextx > xcoord) { if (Bcur + Gcur > Gtot) { ok = false; break; } } // теперь открывающие события на этой же координате while (i < evs.size() && evs[i].x == xcoord && evs[i].type == 1) { Bcur += evs[i].db; Gcur += evs[i].dg; ++i; } } cout << (ok ? "Yes" : "No") << '\n'; } return 0; }

Итог

  • Если девушек меньше, чем юношей — «No».
  • Иначе запускаем сканлайн; если где-то B(t)+G(t)>GtotB(t)+G(t) > G_{\text{tot}} — «No», иначе «Yes».

Если хотите, могу сразу под вас подогнать парсинг пола (какие именно значения приходят в четвёртой строке) или перевести решение на Python/Java.

Condividi questa Q&A