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

Автор Rubanenko, 12 лет назад, По-английски

I've implemented a solution for the last contest's problem D which works correct but dramatically slow! It works more than ten minutes on my PC which seems to be quite slower than naive approach. I divide the data into blocks, and store cnt[] array in every block and a deque for maintaining update queries. I cut blocks sometimes, so I rebuild structure when the number of blocks is above 2 * initialNumberOfBlocks. Probably the problem is that I'm a Java noob, who knows :D

If you have a couple of minutes, please have a look at my code. I tried to make it readable... hope it is :)

Thanks!

UPD

After I fixed the but mentalist found, the program got ML. It's also quite strange because I didn't rely on garbage collector and create no more than 400 Blocks. Each Block has int cnt[100000] inside, so total memory usage should not be more than something about 40 mb, but it exceeds 256 mb on practice. Code

  • Проголосовать: нравится
  • +4
  • Проголосовать: не нравится

»
12 лет назад, скрыть # |
 
Проголосовать: нравится +21 Проголосовать: не нравится

I think the mistake is in the answer procedure. The check if(k > NUMBER_OF_BLOCKS*2) does not use the global k (as i think you intended), but the local parameter.

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

May be deque very slow. Try use arrays instead of deques.

This is author's solution.

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

зачем rebuild?

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

    Потому что есть cut().

    • »
      »
      »
      12 лет назад, скрыть # ^ |
       
      Проголосовать: нравится +5 Проголосовать: не нравится

      то есть блоки непостоянной длины и приходится регулировать их длину? просто я никогда не кодил декомпозицию и по туториалу тоже не понял для чего rebuild

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

        Мне удобно когда начало запроса — это начало какого-то блока. Точно так же с концом. Пишем процедуру, которая режет по какому-то индексу. Когда мы режим блок, то он превращается в два блока. Таким образом количество блоков растет на О(1) после каждого запроса. Поэтому, когда их стало, скажем, два корня из Н, давайте заново все перестроим.

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

I think you can probably blame your MLE on Java's overhead and its garbage collector being flaky at times. As for the slowness, your NUMBER_OF_BLOCKS variable is 100, and you might want to change it to something closer to . As it stands, a query on the whole array will affect 1000 blocks, leading to at least 100 million operations, and pretty expensive operations at that -- not a good thing in a language that's already pretty slow.

»
12 лет назад, скрыть # |
 
Проголосовать: нравится -29 Проголосовать: не нравится

The only explanation is that Java sucks for programming contests and one should use C++. Java is good for enterprise development though.