waxtep1)
Условие
(x>bR||x<bL) лишнее, оно перекрывается условием
B[x]==0.
В условиях
x%d==(bL-1)%d||x%d==(bL-1-lr*2*i)%d обе правые части константы, стоит их вычислить заранее.
Тут два одинаковых деления
x%d, стоит сохранить значение первого и использовать во втором. Не уверен как быстрее.
Думаю цикл типа
for(x=1,#B, if(..., B[x]=g) должен работать побыстрее - он не создаёт новых объектов кроме переменной цикла.
Стоит посмотреть какое условие не срабатывает чаще - его и поставить первым в if.
Вообще весь цикл похож на заполнение нулевых элементов вектора двумя цепочками с постоянным шагом d - может так и сделать, два
forstep(x=if(x0==0,d,x0),#B,d, if(B[x]==0, B[x]=g)) с разными x0 (
(bL-1)%d и
(bL-1-lr*2*i)%d)? Правда их приходится проверять на 0, но это ведь тоже однократно, как и вычисление этих выражений для x0, а не для каждого нулевого элемента как у Вас.
2)
Ваш код работает неправильно если любой край непрерывного куска упёрся в свой край вектора - в этом случае соответствующий указатель не изменится.
Кроме как перебором индексов и проверкой элемента на 0 что-то придумать сложно. Каким именно циклом перебирать указатель думаю разницы мало (я обычно while и вечно парюсь с проверкой на концы вектора).
-- 05.02.2026, 03:57 --Опять же более красивая конструкция работает медленнее:
xz=select(x->(x>bR)&&(B[x]==0),[1..#B])[1]; bR=xz-1;
xz=select(x->(x<bL)&&(B[x]==0),[1..#B]); bL=xz[#xz]+1;
Тут можно сразу поставить пределы
[bR+1..#B] и
[1..bL-1] соответственно и убрать проверки
x>bR и
x<bL, будет быстрее.
Однако если нулей не осталось - всё равно будет работать неправильно, в конце нужна дополнительная проверка на пустой вектор:
bR=if(#xz>0, xz[1]-1, #B) и
bL=if(#xz>0, xz[-1..-1][1]+1, 1).
Но мне сложно представить в каком случае такая конструкция будет быстрее цикла с выходом. Разве что при сильном удлинении непрерывного куска - но такое не может быть часто, а при столь малом векторе выигрыш несколько раз из тысяч (или миллионов или сколько у Вас там итераций) роли не играет.