Ще одна задача про дерева
Дуже складна
Обмеження на час виконання 1 секунда
Обмеження на використання пам'яті 256 мегабайтів
Є граф із вершин. Спочатку він порожній. Потрібно обробити запитів:
додати ребро з вершини до вершини , при цьому вершини і знаходяться в різних деревах і вершина є коренем якогось дерева.
по двох вершинах і визначити, чи лежать вони в одному дереві.
Розв'язання задачі
Реалізуємо СНМ з евристикою стиснення шляхів:
int n, m, l[NMAX]; int calc_leader (int v) { if (l [v]! = v) l[v] = calc_leader (l[v]); return l [v]; } int main() { scanf ("%d%d", &n, &m); for (int i = 1; i <= n; i ++) l[i] = i; for (int i = 1; i <= m; i ++) { int x, y, z; scanf ("%d%d%d", &z, &x, &y); if (z == 1) l[y] = x; else if (calc_leader (x) == calc_leader (y)) printf ("YES\n"); else printf ("NO\n"); } }
Вам же доведеться зробити тест, на якому це рішення працюватиме довго. Більш точно, потрібно зробити тест, на якому кількість викликів функції calc_leader
буде не менше ніж .
Вхідні дані
Вхідний файл містить два цілих числа і (, , ).
Вихідні дані
Виведіть рядків. -ий рядок повинен мати вигляд , якщо -ий запит полягає в додаванні ребра з вершини до вершини , або , якщо питається, лежать чи вершини і в одному дереві.
Приклади
Вхідні дані #1
Відповідь #1
Відправки 321