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

Автор brainail, 14 лет назад, По-русски
Ну вот когда не нада подвисать она подвисает >_<
Сразу скажу =)
1 задача. Лоб
2 задача. ДП по маскам (не успел отправить)
3 задача. Не успел прочитать
Эх .. =(
Теги 471, srm
  • Проголосовать: нравится
  • +18
  • Проголосовать: не нравится

14 лет назад, # |
  Проголосовать: нравится +13 Проголосовать: не нравится
Эх. А я в 2 диве все 3 задачи засабмитил. Но похоже, контест отменяется... :(
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Да-да, а я третью без пяти минут как написал( Если бы отсабмитил, может в 1 див бы попал(
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
1)В лоб???? а по времени успеет?
  • 14 лет назад, # ^ |
      Проголосовать: нравится +17 Проголосовать: не нравится
    Конечно, заводим булевский массив до 10^7
    теперь ищем простые решетом
    которое работает при больших N очень близко к линейной асимптотике
    ну а теперь лоб для поиска с конца, сложно максимум N * D, но как вы знаете это не так, так что всё работает моментально.
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Ну в моем понимании в лоб это полный перебор циклом с проверкой за корень.

      И кстати что успеет это я тоже не уверен....

      1) nloglogn это не n хотя на топкодеровских компах думаю успеет(хотя сам писал решето за линию)
      2) для n=10000000 и d=10 ответ -1 почему прервется быстрее я не понимаю.Я решил это динамикой за туже линию.

      Но думаю раз утверждаете что моментально то скорее всего запустили. а значит это так.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        так, почему nlognlogn?
        это кто так решето пишет?:
        есть простые алгоритмы за O(N) - который тут не нужен
        и за NlogN, который при больших N,как у нас почти линейно работает.

        memset(isPrime, true, sizeof(isPrime));
        isPrime[1] = false;
            for (int x = 2; x <= n; ++x)
                if (isPrime[x])
                 for (int y = x * x; y <= n; y += x) isPrime[y] = false;
        Вот.
               
        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Я допускаю что ошибся я но асимптотически приведенный код работает за nloglogn. Это в принципе не сильно больше чем n. Но все-таки.По поводу при больших n почти линейно сказать ничего не могу не экспериментировал.
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            Вы ошибаетесь, этот код работает nlogn, и даже быстрее так как пометки идут когда мы берём простое, а nlogn, так как получаем примерный ряд n/1 + n/2 + n/3 + n/4 + n/5 .. что равно приблизительно logn.
            А так как мы запускамеся только на простых, которых примерно до числа n - n/ln(10), то судите сами как быстро это будет работать!
            • 14 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится
              Доказательство оценки nloglogn можно почитать тут
              А по поводу практической оценки скорости работы уже сказал не проверял спорить не буду.
              • 14 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится
                Я провёл только что своё иследование :-D
                на 10^7 этот код делает 2 * 10^7 примерно операций. =) Вот она линия :-=D
            • 14 лет назад, # ^ |
                Проголосовать: нравится +5 Проголосовать: не нравится
              Ну правильно, n log log n — это быстрее, чем n log n :)
              • 14 лет назад, # ^ |
                  Проголосовать: нравится +11 Проголосовать: не нравится
                Фак =0 Я развёл тут бардак :-D Не минусуйте =))
                Я прочитал как log^2(n)
                поэтому и возражал =)
                Аррр >__<
        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Этот алгоритм на самом деле работает за N log log N. Ну, правда, в приведённой реализации есть баг с тем, что если первый цикл до x <= n, то во втором цикле int y = x * x переполнится при x порядка 40000. Можно написать в первом цикле до x * x <= n; от этого асимптотика не поменяется, а константа немного улучшится.

          Почему это работает за N log log N? Время работы будет не N + N/2 + N/3 + ... + N/(N - 1) + N/(N) = N * (1 + 1/2 + 1/3 + ... + 1/N) ~ N * log N, а та же сумма только для простых знаменателей: N * (1/2 + 1/3 + 1/5
           + ...).

          Дальше довольно грубо. Простое число асимптотически ведёт себя как P(K) ~ K log K. Простых чисел от 1 до N примерно N / log N. Приблизим сумму интегралом, получим время работы ~ N * int [1 .. N/(log N)] 1/(x log x) dx.

          Заметив, что производная f(x) = log log x равна 1 / x log x, получаем, что время работы примерно равно N * log log (N / log N). Ну или грубо N * log log N, если считать, что количество простых N, а не N / log N.
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Если отмечать уже пройденные на прежней итерации простые числа как составные, то получаем O(N)
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Крепко висит :(
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Что хоть за задачи-то в 1 диве?
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Кто-нибудь знает как третью в div1 решать? Я вот сделал шаманство с использованием рандома, но отослать не успел.
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Я тоже написал шаманство с рендомом и комбинациями нескольких жадностей, но тоже после того как арена зависла :) Кстати, ее человек 8 успело сдать, причем за очень приличное время.
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      А самое смешное что это решение прошло в практис руме :)
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    У меня возникла такая идея:

    длина суммы векторов (x1, y1), (x2, y2), ..., (xn, yn) равна , (если я зафейлил с техом, то сумма квадратов координат плюс удвоенная сумма всех попарных скалярных произведений). В нашем случае первые две скобки - константы, тогда надо максимизировать сумму скалярных произведений.

    Для такой задачи, я надеюсь, есть какой-нибудь алгоритм решения. Получается что-то вроде минимального разреза, но только с отрицательными ребрами и разрез нужен максимальный.

    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Верно, вот только максимальный разрез это NP-полная задача даже с неотрицательными рёбрами
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Непонятно, как это решение учитывает то, что ломаная не должна быть самопересекающейся.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Будем использовать доказательство "от ограничений".
        Утверждение: ломанная с максимально удаленными концами не будет иметь самопересечений (или, по крайней мере, в ней можно так переставить отрезки, чтобы она не имела самопересечений)
        Доказательство: иначе для таких ограничений не придумать решения :о)
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
по первой задаче У меня Решето почему то не прошло. Но я писал
memset(a,1,sizeof(a) );
for(int i=2;i<=n;i++)
if(a[i])
for(int j=2;i*j<=n;j++)
a[i*j]=0;

но кажется для D>=7 ответ всегда -1
для D==6 максимаьлное простое число <=10^8 это 4068479. поэтому n=min(n,4068479)
ну а для остальных делал рекурсию с запоминанием 
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    как это не прошло? сервак же до сих пор того...
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Просто я тестил когда он был нормальный.
       для N=10000000 и D=10 он выдал : 2.001 The code execution exceeded  time limit
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        да там даже на яве нормально все. Может цикл надо по-другому устраивать?
        вместо
        for (int j=2; i*j<=n; j++) a[i*j] = 0
        сделать
        for (int j=i; j*j<=n; j+=i) a[j] = 0
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Тайм лимит на топкодер все знают - 2 секунды, а вот кто нибудь знает какой там мемори лимит? Просто мое вчерашнее решение 250 в котором было два интовых массива по 107  падало с вердиктом segmentation fault, а дома у меня оно спокойно компилилось и выполнялось. (Проблема решалась просто исправить один из массивов на bool, просто еще когда то очень давно, я где то прочитал, что с переменными типа int процессор работает быстрее всего, так как при внесении ее в регистры не нужно выравнивать слово.)
  • 14 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    Ну судя по тому, что ~80 МБ не прокатило, а ~50 МБ зашло, то можно предположить, что ограничение 64 МБ.
  • 14 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    What options are set when starting up the VM?

    java -client -Xmx64m <main class>

    http://www.topcoder.com/wiki/display/tc/General+Algorithm+FAQ


    Я не нашел на это прямого указания, но для C++ и C# ответ такой же - 64 мегабайта

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

    Если уж хотелось сделать побыстрее, то разницы между char и int тут нет. А вообще, это верно только тогда, когда массив целиком помещается в кэше. Для больших массивов память оказывается медленее процессора (и поэтому vector<bool>, упаковывающий в биты, на решете Эратосфена оказывается быстрее массива int -- если конечно не брать случаи плохих компиляторов).