Никто не обсуждал версию BigInteger. Для этого я бы посмотрел на 10 1 , 10 2 , 10 4 , 10 8 и так далее, пока вы не найдете последний 10 2 n , что меньше вашего значения. Возьмите ваш номер div и мод 10 2 n , чтобы получить 2 меньших значения. Вымойте, сполосните и повторите рекурсивно. (Вы должны хранить свои повторяющиеся квадраты 10 в массиве, а в рекурсивной части передавать информацию о следующей используемой мощности.)
Для BigInteger с k цифрами деление на 10 равно O (k). Поэтому нахождение суммы цифр с помощью наивного алгоритма равно O (k 2 ).
Я не знаю, что C # использует внутренне, но не наивные алгоритмы для умножения или деления k-бита на k-битное целое все работают за время O (k 1.6 ) или лучше (большинство намного, намного лучше, но имеют издержки, которые делают их хуже для «маленьких больших целых чисел»). В этом случае подготовка вашего начального списка степеней и разделение за один раз занимает время O (k 1.6 ). Это дает вам 2 задачи размера O ((k / 2) 1.6 ) = 2 -0.6 O (k 1.6 ). На следующем уровне у вас есть 4 задачи размера O ((k / 4) 1.6 ) для другой 2 -1.2 O (k 1.6 ). Сложите все слагаемые и степени 2 превращаются в геометрический ряд, сходящийся к константе, поэтому общая работа составляет O (k 1.6 ).
Это определенный выигрыш, и выигрыш будет очень и очень очевидным, если вы работаете с числами из многих тысяч цифр.