Количество раз, которое мы посещаем k -й элемент в списке с n элементами, а v посещений составляет ⌈ (vk) / n⌉, что эквивалентно ⌊ (v-k + n-1) / n⌋.В конце концов, мы совершаем v посещений, что означает, что каждый элемент посещает не менее ⌊v / n-1⌋.Последний «раунд» распределяет оставшиеся v - ⌊v / n-1⌋ , а первые v - ⌊v / n-1⌋ элементов «возвращают» посещение.
Мы можем сгенерировать такой список за линейное время с помощью:
def visit_count(data, v):
n = len(data)
return [(x, (v-i+n-1)//n) for i, x in enumerate(data)]
Например:
>>> visit_count('abc', 7)
[('a', 3), ('b', 2), ('c', 2)]
>>> visit_count('abc', 8)
[('a', 3), ('b', 3), ('c', 2)]
>>> visit_count('abc', 9)
[('a', 3), ('b', 3), ('c', 3)]
>>> visit_count('abc', 10)
[('a', 4), ('b', 3), ('c', 3)]
Так как это выполняется в длине списка, а не вКоличество посещений означает, что мы можем решить эту проблему за разумные списки и за огромное количество посещений.Например:
>>> visit_count('abcde', 1_234_567_890_123_456)
[('a', 246913578024692), ('b', 246913578024691), ('c', 246913578024691), ('d', 246913578024691), ('e', 246913578024691)]
Ведение учета для 1'234'567'890'123'456 посещений по отдельности приведет к тому, что функция получит возраст для получения результата.Но так как количество элементов (здесь 5) ограничено, это займет всего несколько микросекунд.