Лінійна мережа#10455

Лінійна мережа (Розбір)

Комп'ютери пронумеровані числами від до . Оскільки n \le 10^9, інформацію про стан робочих і несправних комп'ютерів будемо зберігати у відображенні map\langle int, int \rangle m. Значення m[i] = 0, якщо комп'ютер з номером працює, і m[i] = 1, якщо він зламаний. Спочатку для всіх 1 \le i \le n покладемо m[i] = 0.

Для зручності введемо два фіктивних зламаних комп'ютери з номерами та n + 1. Задамо значення m[0] = m[n + 1] = 1.

Кількість груп комп'ютерів у мережі будемо підтримувати у змінній . Спочатку в мережі є одна група, тому покладемо cnt = 1.

Тепер розглянемо процес обробки запитів. Зокрема, розберемо поломку комп'ютера з номером (запит типу t = 1):

Для обробки запиту типу t = 2 достатньо вивести поточне значення змінної .

Приклад

Реалізація алгоритму

Оголосимо структуру даних map.

map\langle int, int \rangle m;

Читаємо кількість комп'ютерів і кількість запитів .

scanf("%d %d", \u0026n, \u0026q);

Ініціалізуємо фіктивні комп'ютери з номерами і n + 1.

m[0] = 1;
m[n + 1] = 1;

Кількість груп комп'ютерів у мережі будемо підтримувати у змінній . Спочатку всі комп'ютери робочі, тому cnt = 1.

cnt = 1;

Послідовно обробляємо запитів.

while (q--)
{
  scanf("%d", \u0026t);
  if (t == 1)
  {

Запит t = 1. Комп'ютер з номером виходить з ладу. Якщо комп'ютер вже був зламаний, ніяких дій не потрібно.

    scanf("%d", \u0026l);
    if (m[l] == 0)
    {

В протилежному випадку встановлюємо стан комп'ютера як зламане.

      m[l] = 1;

В залежності від стану сусідніх з комп'ютерів (робочих або зламаних) перераховуємо кількість груп:

      k = m[l - 1] + m[l + 1];
      if (k == 2) cnt--;
      else if (k == 0) cnt++;
    }
  }
  else

Для запиту t = 2 виводимо поточну кількість груп комп'ютерів у мережі.

    printf("%d\n", cnt);
}