Москва только хорошеет с годами. Так в году ...
Creato il: 2 settembre 2025
Risposto usando GPT-5 Thinking da Chat01
Creato il: 2 settembre 2025
Risposto usando GPT-5 Thinking da Chat01
Москва только хорошеет с годами. Так в
году вдоль серой ветки построили бесконечное количество зданий, которые нумеруются всеми возможными целыми числами.
Хоть у студентов ВШЭ и большая стипендия, но вместе с бесконечным количеством домов в Москве появился бесконечный спрос на жилище. Поэтому студентам приходится снимать квартиры группами.
Всего есть
групп студентов, причем известно, что
-я группа состоит из
студентов, которые решили поселиться в доме
. Из-за бытовых особенностей каждая группа состоит из студентов одного пола
, для юношей выполняется
, а для девушек —
.
Каждая группа студентов также регулярно выходит на прогулки, в ходе которых посещает участки серой ветки из какой-то окрестности их дома, не отходя от своего дома на расстояние большее, чем
. Из-за этих прогулок студенты иногда знакомятся друг с другом. Будем считать, что студенты из группы
знакомы со студентами из группы
, если выполнено
.
Каждый студент-юноша решил найти себе ровно одну онлайн-подружку, которая тоже учится во ВШЭ и с которой он на данный момент не знаком. Студенты волнуются, что если у одной девушки появится сразу два онлайн-друга, то у нее не хватит времени на учебу, и она отчислится, поэтому они хотят избегать такой ситуации.
Вам требуется определить, смогут ли все студенты-юноши найти себе по онлайн-подружке так, чтобы никакая пара юношей не подружилась с одной и той же девушкой.
Обратите внимание, что если нет ни одного юноши, который учится в ВШЭ, то ответ на задачу «Yes».
Формат входных данных
В первой строке вам дано число
— количество тестовых наборов. Следующие строки содержат описания тестовых наборов.
В первой строке каждого набора содержится целое число
(
).
Во второй строке указаны числа
(
).
В третьей строке указаны числа
(
).
В четвертой строке указаны числа
(
).
В пятой строке указаны числа
(
).
Гарантируется, что сумма
по всем тестовым наборам не превосходит
.
Формат результата
Для каждого теста в отдельной строке выведите «Yes» (без кавычек), если каждый из юношей может найти себе по уникальной онлайн-подружке, и «No» (без кавычек) иначе.
Похоже, что у вас «интервальная» задача про знакомства на серой ветке. Удобно свести её к отрезкам:
Значит, каждый юноша со своим отрезком может «матчиться» только с девушками, чьи отрезки лежат целиком слева от его или целиком справа от его . Это типичная задача про паросочетание в «интервальном» двудольном графе, и у неё есть простой критерий выполнимости, который удобно проверять «линией сканирования».
Обозначим:
Рассмотрим произвольную точку на оси домов и величины:
Юноши, чьи отрезки покрывают , не могут выбрать девушек, чьи отрезки тоже покрывают . Для них доступны только девушки, чьи отрезки целиком вне точки , т.е. .
Чтобы всех юношей можно было разобрать по уникальным девушкам, нужно и достаточно:
Интуиция: «узкие места» возникают только в точках разбиения прямой — внутри каждого «промежутка» между соседними концами отрезков набор покрывающих групп не меняется, и именно там выполняются (или рушатся) условия Холла. Поэтому достаточно проверить условие в этих точках.
Сделаем «сканлайн» по событиям начала/конца отрезков отдельно суммируя мальчиков и девочек.
Для каждой группы :
Соберите все события (две мультисортированные ленты или одна с пометкой пола).
Упорядочьте по координате; при одинаковой координате сначала применяйте «закрывающие» события , потом «открывающие» — так внутри полуинтервала покрытие считается верно.
Пробегая слева направо, поддерживайте текущие суммы и .
В каждом «стабильном» промежутке между соседними событиями проверяйте:
Если нарушено — ответ «No».
Отдельно перед сканлайном проверьте . Если нет — «No».
Если юношей нет вовсе () — по условию сразу «Yes».
Все суммы держите в 64-битных целых.
В вашем описании 5 строк на тест:
'M'/'F'
или 0/1
— используйте то, что дано);Дальше для каждого теста печатаем 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; }
Если хотите, могу сразу под вас подогнать парсинг пола (какие именно значения приходят в четвёртой строке) или перевести решение на Python/Java.