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

Автор dmkozyrev, история, 8 лет назад, перевод, По-русски

Здравствуйте! Идеи, как решить следующую задачу, зашли в тупик, поэтому нужна помощь:

У нас есть массив a[1...n] (n ≤ 200000, 1 ≤ a[i] ≤ 1000000) из целых чисел и есть q запросов к этому массиву (q ≤ 200000) вида: li, ri, xi (1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 1000000). Для каждого запроса мы должны ответить сколько есть различных индексов j таких что li ≤ j ≤ ri и gcd(a[j], x) = 1.

Вот, что удалось осознать:

1) До 1.000.000 всего 78.498 простых чисел.

2) Каждое число во вводе не может иметь более 7 различных простых делителей, так как 2 × 3 × 5 × 7 × 11 × 13 × 17 = 510.510

3) Задачу можно решать только на префиксе, так как: count(li, ri, xi) = count(1, ri, xi) - count(1, li - 1, xi), li > 1

Ограничения по времени 1.5 с, памяти 32 MB.

Задача была на полуфинале ВКОШП в Красноярском крае в сезоне 2017/2018 как задача "G. Скучные запросы". Разбор и архив жюри найти не удалось, а очень хочется. Здесь ее можно сдать, ограничения по времени немного увеличены в сравнении с оригиналом, так как сервер не самый быстрый, а система 32-битная.

Пример:

6
1 2 3 4 5 6
4
1 6 1 --> 6
1 6 2 --> 3
2 4 6 --> 0
3 6 10 --> 1

UPD: решено Aeon. Memory: 21 MB, Time: 1.2 s на худшем случае.

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

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

https://www.codechef.com/MARCH18A/problems/GCDCNT same problem but with assign queries

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

I would use lower_bound and inclusion-exclusion principle.

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

    Can you tell me your idea in more detail?

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

      Несколько замечаний:
      1) Нас интересуют только простые делители числа (их не больше 7)
      2) Значит не больше 2^7 комбинаций простых делителей
      3) Ответ на отрезке [l, r] для x можно представить как ответ для комбинаций простых делителей
      4) Комбинации ограничены сверху 1000000
      Исходя из этого, можно построить алгоритм за O(NlogN × 128) или даже за O(N × 128)

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

        Thanks! I hope that I will succeed in this.

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

        Какую оценку по памяти мы можем достичь? Я посчитал, что если хранить в массиве d[v] для каждого числа v все позиции чисел, которые на него делятся, для бин.поиска при подсчете количества, то выходит 97 МБ в худшем случае (128*200000*4 байта), что лежит за пределами по времени.

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

          128*1000000*4 ~ 50 mb

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

            Похоже, что это 488 МБайт:

            128 * 1000000 * 4 / 1024 / 1024 ≈ 488.28125

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

              Да верно.

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

              Вообще будет (128*200000+1000000)*4 ~ 100 mb, но 7 делителей только в худшем случае, так что я бы рискнул (в среднем будет 4-5 делителя).

              Кроме того, можно разделить отрезок на левый и правый запрос и избавиться от бинарного поиска, обрабатывая запросы в оффлайне.

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

                Основная проблема сдать задачу с такими ограничениями. Не знаю зачем школьникам давать жесткие ограничения в TL/ML.

                Очень интересно действительно ли у авторов решение с двукратным запасом по времени, потому что сайт что-то слишком медленный.

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

                  В оригинале даже трёхкратный запас, олимпиада была на yandex.contest.

                  На acmp работает 3 секунды.

                  Sorry for my english

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

                  Получаю MLE 6.

                  Предполагает ли авторское решение дополнительные оптимизации памяти?

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

                  авторское ест 16-17 МБ

                  никаких спец оптимизаций нет, даже наоборот, местами неоптимально

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

                  Добавил корневую декомпозицию запросов, получаю TLE 8. МО ожидалось?

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

                  Нет :)

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

                  Забавно :)

                  • наивный upper_bound по комбинациям простых делителей получает TLE 6
                  • сортировка запросов в оффлайне получает MLE 6
                  • сортировка запросов в оффлайне + МО получает TLE 8

                  Какое решение ожидалось автором? :)

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

                  Включения-исключения, оффлайн, выше вроде про него уже написано, но нужно за O((N + M) × 27)

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

                  я также сдал, но что-то мало верится, что там не пришлось делать оптимизации по памяти.

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

                  мм, я кажется понял

                  у вас что-то вроде O(NlogN) памяти для делителей?

                  в авторском этого нет, делители числа просто генерятся рекурсией по простым

                  если для вас это оптимизация, то прошу простить :)

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

                  Для делителей хранил только простые делители.

                  Оптимизации, которые пришлось сделать.

                  1) хранить простые делители только для чисел, которые присутствуют в запросах или в массиве

                  2) все вектора пришлось убрать и переписать на массивы.

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  8 лет назад, скрыть # ^ |
                  Rev. 2  
                  Проголосовать: нравится +3 Проголосовать: не нравится

                  Чтобы сдать пришлось использовать 2 оптимизации, вектора присутствуют:

                  1) генерация делителей из простых

                  2) 27 вместо 27 * 7

                  code

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

                  Наконец-то зашла с 4с и 16 мб. Перебор делителей за 2^7 и оффлайн с O(N) памяти для делителей я все же считаю оптимизацией :)

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

                  Спасибо! После замены cin / cout на scanf / printf из stdio.h решение показало 3.374 с по времени и 21 МБ по памяти на медленном сервере и 2.4 с и 23 МБ на быстром сервере, что примерно означает не более 1.2 с по времени на сервере yandex.contest. На самой олимпиаде эту задачу не решила ни одна из команд.

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

                  actually, i submit run with scanf/printf and got TLE on test 10, when i replace them with fast cin/cout i got AC

                  i don't understand russian but google translate help

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

                  acmp.ru server: Core 2 Quad 2.4 MHz, Windows XP 32 bit, MinGW.

                  This code: 3.374 s and 21 MB

                  This code: 2.874 s and 23 MB

                  Original: 4.842 s and 21 MB

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

                  прости, Виталя, я не смог ее решить самостоятельно

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

                  Отправил решение. Получило ML на 5 тесте. Из больших объектов храню только различные делители всех n чисел (1 млн) и решето (1 млн чисел). Как думаете, в чем дело?

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

Автокомментарий: текст был переведен пользователем dmkozyrev (оригинальная версия, переведенная версия, сравнить).

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

Inclusion_Exclusion principle: we want to compute count(1, L, x) which is number of elements which are coprime with x, so let x = 6 which has 2, 3 primes

main information we need are how many numbers up to index L has 2 as factor, the same for 3, 6 lets call them C(L, 2), C(L, 3), C(L, 6)

and compute number of coprimes by In_Ex, ans = L — C(L, 2) — C(L, 3) + C(L, 6)

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

i don't know if there is better way but to compute C(L, y)

let vector d[N];

where d[j] contains indices of all elements of array Ai where j|Ai

so C(L, y) = lower_bound(d[y], L)

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

Автокомментарий: текст был обновлен пользователем dmkozyrev (предыдущая версия, новая версия, сравнить).

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

Auto comment: topic has been updated by dmkozyrev (previous revision, new revision, compare).

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

Автокомментарий: текст был обновлен пользователем dmkozyrev (предыдущая версия, новая версия, сравнить).