Хорошо, по всей видимости объяснить все у меня действительно не получилось.
Давайте еще раз с самого начала. У нас есть
. Что она из себя представляет описано подробно в первом посте. Первый значимый член у
- это
. Наипримитивнейшая рекурсия базируется на том, что задано
.
Введем дополнительно
, чтобы работать с последовательностью, у которой первый значимый член это
. Это позволит нам увидеть новые закономерности.
Пусть также
- это
A284005. Не суть важно что это за последовательность. Нам нужно знать только, что
можно получать через обратную биномиальную трансформацию по модулю
последовательности
:
где
- это
A000120, двоичный вес
или же число единиц в двоичной записи
.
Перебирать все
, проверяя остаток от деления бинома на
- это долго и неудобно. На этот случай существует эквивалентная формула, где слагамые
генерируются сразу для
. Вот как она выглядит на страничке
A329369:
Цитата:
a(n) = Sum_{j=0..2^wt(n) - 1} (-1)^(wt(n) - wt(j)) Product_{k=0..wt(n) - 1} (1 + wt(floor(j/2^k)))^T(n,k) for n > 0 with a(0) = 1 where wt(n) = A000120(n), T(n,k) = T(floor(n/2), k - n mod 2) for k > 0 with T(n,0) = A001511(n) (equivalent to theorem 6.3 at page 296, see R. Ehrenborg and E. Steingrimsson link). Here T(n, k) - 1 for k > 0 is the length of the run of zeros between k-th pair of ones from the right side in the binary expansion of n. Also this formula is equivalent to inverse modulo 2 binomial transform of A284005.
Назовем эту эквивалентную формулу
исходной и лучшей на данный момент (пока я так и не организовал то, что я хочу) для вычисления индивидуального члена
без использования рекурсии. Рекурсия мне не нужна от слова совсем.
Теперь о том, что я, собственно, обнаружил. Вот первая формула (та самая, про которую нигде ничего не было сказано):
Т.е. если
(двоичная запись), то
Т.е. мы можем как бы "нарастить" в двоичной записи слева две единицы и
нулей.
Аналогично существует вторая формула (про которую также нигде ничего не было сказано):
Здесь все также
, но уже
Т.е. "наращивается" всего одна единица и все также
нулей.
Обе формулы справедливы для
, однако вторая при
не имеет смысла (легко догадаться почему).
В обоих формулах
. Кроме того,
и
это две вспомогательные последовательности, которые генерятся относительно несложно, если только понимать этот механизм.
Теперь, собственно, программки:
default(parisizemax,2^8*10^6)
l(n)=logint(n,2)
a(n)=my(n=(n+1)/2^valuation(n+1, 2)-1, wt=hammingweight(n), v=[], A=0); if(n==0, 1, for(i=0, logint(n, 2), if(bittest(n, i), v=concat(v, A); A=0, A++)); sum(j=0, 2^wt-1, (-1)^(wt - hammingweight(j))*prod(k=0, wt-1, (1 + hammingweight(j\2^k))^(v[k+1] + 1))))
b(n)=a(n-1)
f1(n)=my(m=2*n-1, A=0, v=[], v1); for(i=0,l(m),if(bittest(m,i),v=concat(v,A); A=0, A++)); v=Vecrev(v); if(n==1, [8,6], v1=vector(#v,i,vector(i,j,0)); for(j=1,#v,v1[#v][j]=[2*(#v-j+4),2*(#v-j+3)]); for(i=1,#v-1,for(j=1,#v-i,v1[#v-i][j]=[(#v-j+4-i+1)^(v[#v-i]+1)*v1[#v-i+1][j][1]-(#v-j+3-i+1)^(v[#v-i]+1)*v1[#v-i+1][j][2],(#v-j+3-i+1)^(v[#v-i]+1)*v1[#v-i+1][j+1][1]-(#v-j+2-i+1)^(v[#v-i]+1)*v1[#v-i+1][j+1][2]])); v1)
f2(n)=my(m=2*n-1, A=0, v=[], v1); for(i=0,l(m),if(bittest(m,i),v=concat(v,A); A=0, A++)); v=Vecrev(v); if(n==1, [6,6], v1=vector(#v,i,0); v1[#v]=[9,6]; my(B=f1(n), v2=[]); for(i=1,#B,v2=concat(v2,B[i][i][2])); for(i=1,#v-1,v1[#v-i]=[v2[#v-i]*3/2,3^(v[#v-i]+1)*v1[#v-i+1][1]-2^(v[#v-i]+1)*v1[#v-i+1][2]]); [v1[1][1]*2/3,v1[1][2]])
f3(n,k)=my(A=b(2*n-1), B=f2(n)); 3^k*B[1]-2^k*B[2]+A
f4(n,k)=my(A=b(2*n-1), B=b(2*n-1+2^(l(2*n-1)+1))); 2^(k-1)*(A+B)-A
m=5
\\ for(i=1,299,print(f3(i,m)-b(2*i-1+3*2^(l(2*i-1)+m)))) \\ проверка первой формулы где m может быть любым натуральным
\\ for(i=1,299,print(f4(i,m)-b(2*i-1+2^(l(2*i-1)+m)))) \\ проверка второй формулы где m может быть любым натуральным
f5(n)=my(v=[1,1]); for(i=1,n-1,v=concat(v,[0,1,1])); v=Vecrev(v); fromdigits(v,2)
\\ for(i=1,100,print(b(f5(i)))) \\ иллюстрация того, как медленно считается по исходной формуле
v=vector(100,i,0)
v[1]=3
\\ for(i=2,100,my(B=f2((f5(i-1)+1)/2)); v[i]=3^2*B[1]-2^2*B[2]+v[i-1]) \\ иллюстрация выгоды от использования первой формулы (считает 99 членов за 6 секунд)Эффективность первой формулы проиллюстрирована на примере вычисления члена с номером в двоичной
Теперь еще раз о том, что мне нужно. У меня есть две формулы. Если все пробеги единиц в двоичной записи
имеют четную длину (кроме крайнего справа, там это не важно), то мы просто применяем многократно первую формулу и имеем результат. В процессе ее применения мы вычисляем все последовательно, наращивая каждый раз пару единиц слева (и нули если нужно). Это рекурсия в определенном смысле, но не такая, что мы создаем массив из
элементов и проверяем каждое на то, вычислено оно или нет (и если нет, то вычисляем), а как бы
последовательно наращиваем значения не для всех, а лишь для выборочных членов последовательности. Как они будут выбираться, очевидно из двоичной записи
.
И теперь, собствено, вопрос (в который раз уже задаю его): как организовать вычисления, чтобы применяя либо первую, либо вторую формулу нарастить к сплошной последовательности единиц справа все необходимые нули и единицы слева?