Предыдущие решения не являются оптимальными. Сложность точно равна в вызовах RandNum50 и подробно описана здесь с использованием в качестве источника случайного бита (как предложено Vor):nlogn+O(1)
if ( rand50() > 25 ) then b = 1 else b = 0 // random bit
Основная идея заключается в том, что вы экономите много битов, если генерируете униформу от дои затем, используя факториальную базовую декомпозицию , вместо генерации последовательности униформ в диапазоне до , затем , затем и т. д., . Это на самом деле, как я уже упоминал в посте, тема статьи, которую я представил!п ! 1 2 3 н1n!123n
Если вы не знаете, как сгенерировать униформу, как предлагается в этом посте, из случайного бита, вы также можете сгенерировать аппроксимацию униформы напрямую, таким образом (что эквивалентно «истинно» Вора, но быстрее):
P = (RandNum50()-1) + (RandNum50()-1)*50^1 + (RandNum50()-1)*50^2 + ...
идти так далеко, как вам нужно пойти. Это развивается в базе . Тогда просто усеченный , т.е. , в вашем случае, Это значение не является полностью случайным, но это мера однородности, которая часто используется. Или, как говорит Вор, вы можете отказаться , если . Затем с этим значением, вы можете сделать расширение факторных баз , как описаны в посте .50 P Q = PP50PQ=Pmodnn=100!P>n