Изменения рейтингов за последние раунды временно удалены. Скоро они будут возвращены. ×

Блог пользователя ardmn

Автор ardmn, 15 лет назад, По-русски
Уважаемые пользователи сайта , пожалуйста поделитесь хорошим классом Длинки(+,-,/,%,*). Свой писал но вроде медленный. Не получается модернизировать. Хорошим в смысле быстрой роботы .
Буду очень благодарен. 
  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

15 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится
http://shygypsy.com/tools/ (BigInt.cpp)
Если нужно более быстрое *, то можно это http://e-maxx.ru/algo/fft_multiply заюзать еще.

P.S. а какой язык? =)
15 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Я обычно юзаю JAVA для этого но бывает мозгов не хватает написать быстрое решение и приходится кодить на С++.По этому хочу у опытных опросить проверенный временем class  :) 
15 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

http://www.everfall.com/paste/id.php?fhelgcbkw1cf

вот весьма эффективная длинка, битовый подход, основание 2^32

многое можно соптимизировать, но это я писал давно и небыло цели особо извращатся.

реализация деления за n^2 * log(base) = n^2 * 32, можно за n^2 реализовать по кнуту, по моим тестам

в 6 или 12 раз быстрее если цифру брать за 8 или 16 бит соответственно

15 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится
Вот вроде-бы одна из самых быстрых библиотек длинки для с++ но не знаю насколько она применима на контестах.
15 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

со встроенной karatsubaMultiply.
  • 15 лет назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится
    тут через вектор :) не плохо но как я заметил , даже не знаю почему но по ходу вектор дольше работает чем обычный массив ... (кстати интересно почему? если это правдатак )
    • 15 лет назад, скрыть # ^ |
      Rev. 3  
      Проголосовать: нравится +3 Проголосовать: не нравится
      Может быть если не делать много push_back'ов, а выделить сразу памяти сколько надо через resize, то вектор будет работать также быстро как и обычный массив.

      Хотя я хз, сам бы хотел узнать где вектор и в чем проигрывает, если проигрывает.
      • 15 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Есть догадка что при push_back'ах создается еще один вектор на 1 элемент больше, ну и дальше там идет переадресация. Просто кто-то мне рассказал что на операцию push_back() вектор тратит в два раза больше памяти чем нужно. Этот человек так же рассказал что на операцию pop_back() вектор тратит в 4 раза больше чем нужно(интересно, почему). Но если действительно все делать через resize() то время экономится.
15 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится
Оптимизация ДА зависит от конкретного случая
Можно сделать крайне быструю длинку со следующими эвристиками:
1. использовать 10^k как основание системы счисления, если результат нужен десятичный.
2. использовать кэширование при умножении на короткое.
и т.п.

15 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

В Харькове на сборах рассказывался алгоритм Карацубы и Быстрое преобразование Фурье. Эти алгоритмы выполняют умножение за NlogN.  При этом как я понял БПФ лучше работает с базой 10, а не 10^9. 

В случае если необходимо реализовать операцию сложения, то стоит избавляться от долгой операции %. Были задачи, когда эта оптимизация спасает. 

Аналогичный случай с умножением за N^2. Необходимо избавиться от %. Дмитрий Жуков говорил, что подобная оптимизация может помочь, даже в том случа если на первый взгляд решение пройти не может.

  • 15 лет назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится
    Карацуба разве не за O(n^1.6)?
    В БПФ с базой 10^9 происходят на больших числах(1000 знаков) какие-то странные то ли переполнения, то ли потери точности. Факт в том что несколько(штук 8-10) последних знаков наверняка неправильна. Не знаю, я где-то лажал или еще что, но если ставить основание поменьше(10^4 , например) - то все ок.
15 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
И ещё у Карацубы большая константа, из-за этого его примень стоит только на больших числах