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

Автор savinov, 13 лет назад, По-русски

Приветствую всех! На днях я решал задачу, в которой требовалось определить, представимо ли число N < 1015 в виде суммы двух квадратов. И у меня возникли проблемы с этим, банальный перебор за корень давал TL. Так же пробовал разложить на простые сомножители за тот же корень, и потом проверял четность степеней у простых делителей вида 4k + 3, опять же TL. Скорее всего задача сдается за корень, и мне интересно именно техническая реализация этого, т.е. как конкретно писать аккуратный перебор или факторизацию за корень, и в чем конкретно проявляется эта аккуратность. Если что, эта задача с тимуса link HERE Заранее благодарен!

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

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

Заводим 2 указателя i и j. Изначально i = 1, . На каждой итерации увеличиваем i на единицу, а j уменьшаем до тех пор, пока i2 + j2 > n. Когда-нибудь получится, что i2 + j2 = n. Либо не получится, если число непредставимо в виде суммы двух квадратов.

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

    Вот кусок моего кода, который я сдавал где-то год назад:

    bool two_square(ll x){
    	ll i,j,en=(ll)(sqrt((double)x));
    	for (i=1,j=en;i<=j;i++){
    		while (i*i+j*j>x) --j;
    		if (i*i+j*j==x) return 1;
    	}
    	return 0;
    }
    
  • »
    »
    13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Можно же просто завести 1 "указатель", а второй считать, просто идти не до n а до корня

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

      тогда будет тратиться время на извлечение корня в double. Может получиться дольше, наверно)

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

      Если я правильно понял, то на каждой итерации у вас будет вызываться функция sqrt. Такое решение невозможно сдать из-за TL, всё-таки извлечение корня — довольно трудоемкая операция.

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

        Ок.

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

        У меня прошло и с sqrt. Код

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

          Весело. Что-то я не подумал так ускорить. У меня было немного более "влоб" и падало по тайму где-то после 10ого теста.

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

          корень не обязательно каждый раз извлекать, можно что-то возводить в квадрат, а можно воспользоваться тем что (x+1)^2 == x^2+2x+1 и каждый раз прибавлять/вычитать 2x+1

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

            Вроде еще можно предпросчитать квадраты в хеш таблицу до 10^7, тогда непокрытых будет немного. Я как то так сдавал когда-то.

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

How can you use an algorithm that checks N = a²+b² in the problem you linked? It asks for the minimum number of squares that sum to N, am I right?

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

according to me we can run a loop in which 'i' goes from 1 to sqrt(N/2) and if N-i*i is a perfect square we are done....

for(int i=1; i*i<=N/2; i++) { if((N-i*i) is a perfect square) done; }

its complexity is O(sqrt(N)).....

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

    How do you check number for square? I did the same and used sqrt() and got TL.

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

An arbitrary positive number n is expressible as the sum of two squares iff, given its prime factorization

n=p1^(a1)p2^(a2)p3^(a3)...pk^(ak),

none of pi^(ai) +1 is divisible by 4 (Conway and Guy 1996, p. 147). http://mathworld.wolfram.com/SquareNumber.html