Разбор
Заведем массив — счетчик . Для каждого запроса выполним две операции: и . Таким образом, частичная сумма будет равна количеству монет в -ой копилке.
Количество дней, в которые Рой совершает действия, не превышает . Каждый день он кладет в каждую копилку не более одной монеты. После выполнения всех действий в каждой копилке будет находиться не более монет. Заведем массив размера и занесем в количество копилок с суммой . Для этого для каждой частичной суммы положим .
Вычислим количество копилок, которые содержат как минимум монет. Для этого в массиве пересчитаем его частичные суммы справа налево (то есть с конца). Тогда количество копилок, которые содержат как минимум монет, будет равно .
Пример
Получим следующее распределение монет по копилкам:
Количество копилок с суммой . Частичные суммы (подсчитанные справа налево) содержат количество копилок, содержащих как минимум монет.
Имеются одна копилка с суммой (копилка номер ), две копилки с суммой (копилки номер и ), три копилки с суммой (копилки номер и ), одна копилка с суммой (копилка номер ).
Вычислив частичные суммы массива , можно утверждать, например, что существует копилок, содержащих как минимум монету. Или что существует копилки, содержащих как минимум монеты.
Реализация алгоритма
Объявим рабочие массивы.
#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])