хранилище - это гиперкуб
n = len(lst)
while i < n:
if len(lst[i]) == 1:
lst.pop(i)
n -= 1
else:
i += 1
P1(n, 0) = 1 - sum_{i = 1..n-m} P1(i, 0) - sum_{j>0, PI^j(m) > 0} P1(PI^j(m) + n -m, 0) / (Prob(s[1])*Prob(s[2])*...*Prob(s[PI^j(m)])
PI^j(m)
- это j раз применить префикс функцию к строке. Похожую формулу можно составить для P2(m, k). Этот метод тоже работает за O(nm), но чуть быстрее, потому что более точная оценка O(nl), где l - сколько раз нужно применить префикс функцию к строке, пока не получится пустая 0. Для строки из одних и тех же символов l=m, но обычно сильно меньше. А еще он требует лишь O(n+m) памяти.
Непонятно. Ваш код на питоне не делает никакой адресации, там заводится список! Смотрите в байт код.
Если вы хотели сделать что-то вроде
storage[[a,b,c,d]].val
илиstorage[a][b][c][d].val
(через многомерные массивы), то там будет то же самое а то имедленнее, что код на С++, что привел я - вычисление адреса или несколько индексаций.Сумма в любом случае быстрее.