Заведемо масив — лічильник . Для кожного запиту [l, r] виконаємо дві операції: cnt[l]++ та cnt[r + 1]--. Таким чином, часткова сума \displaystyle\sum_{j = 1}^i cnt[j] буде дорівнювати кількості монет у -й скарбничці.
Кількість днів, у які Рой здійснює дії, не перевищує 10^6. Кожен день він кладе в кожну скарбничку не більше однієї монети. Після виконання всіх дій у кожній скарбничці буде знаходитись не більше 10^6 монет. Заведемо масив розміру 10^6 і внесемо в кількість скарбничок із сумою . Для цього для кожної часткової суми sum = \displaystyle\sum_{j = 1}^i cnt[j] покладемо coins[sum]++.
Обчислимо кількість скарбничок, які містять як мінімум монет. Для цього в масиві перераховуємо його часткові суми справа наліво (тобто з кінця). Тоді кількість скарбничок, які містять як мінімум монет, буде дорівнювати .
Приклад
Отримаємо наступний розподіл монет по скарбничках:
Кількість скарбничок із сумою . Часткові суми (підраховані справа наліво) містять кількість скарбничок, які містять як мінімум монет.
Є одна скарбничка із сумою (скарбничка номер ), дві скарбнички із сумою (скарбнички номер і ), три скарбнички із сумою (скарбнички номер і ), одна скарбничка із сумою (скарбничка номер ).
Обчисливши часткові суми масиву , можна стверджувати, наприклад, що існує скарбничок, які містять як мінімум монету. Або що існує скарбнички, які містять як мінімум монети.
Реалізація алгоритму
Оголосимо робочі масиви.
#define MAX 1000010
int cnt[MAX], coins[MAX];Читаємо вхідні дані. Будуємо масив .
scanf("%d %d",&n,&m);
for(i = 0; i < m; i++)
{
scanf("%d %d",&l,&r);
cnt[l]++; cnt[r+1]--;
}У змінній підраховуємо часткові суми масиву . -а часткова сума дорівнює кількості монет у -й скарбничці. дорівнює кількості скарбничок із сумою .
sum = 0;
for(i = 1; i <= n; i++)
{
sum += cnt[i];
coins[sum]++;
}У масиві перераховуємо його часткові суми справа наліво.
for(i = MAX - 2; i >= 0; i--)
coins[i] += coins[i+1];Читаємо кількість запитів . Для кожного запиту читаємо значення і виводимо відповідь .
scanf("%d",&q);
for(i = 0; i < q; i++)
{
scanf("%d",&x);
printf("%d\n",coins[x]);
}Python реалізація
Оголосимо робочі списки.
MAX = 1000010
cnt = [0] * MAX
coins = [0] * MAXЧитаємо вхідні дані.
n = int(input())
m = int(input())Будуємо список .
for _ in range(m):
l, r = map(int, input().split())
cnt[l] += 1
cnt[r + 1] -= 1У змінній підраховуємо часткові суми списку . -а часткова сума дорівнює кількості монет у -й скарбничці. дорівнює кількості скарбничок із сумою .
sum = 0
for i in range(1, n + 1):
sum += cnt[i]
coins[sum] += 1У масиві перераховуємо його часткові суми справа наліво.
for i in range(MAX - 2, -1, -1):
coins[i] += coins[i + 1]Читаємо кількість запитів . Для кожного запиту читаємо значення і виводимо відповідь .
q = int(input())
for _ in range(q):
x = int(input())
print(coins[x])