Задача K Минимум в Полиноме

120
24 апреля 2019, 04:30

Вот такая задача на Нахождение K-ого минимума, написал такой код(На базовых примерах работает, на тестах все кроме 1 завалены): Помогите найти ошибку или исправить код пожалуйста

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
int main() {

    ifstream inp;
    ofstream otp;
    inp.open("input.txt");
    otp.open("output.txt");
    uint64_t n = 0, k = 0, a = 0;
    vector<uint64_t> P(5000000);
    inp >> n >> k;
    for (int i = 0; i < n; i++) {
        P[i] = 132 * pow((i+1), 3) + 77 * pow((i+1), 2) + 1345 * (i + 1) + 1577;
    }
    a = P[k] % 1743;
    otp << a;
    return 1;
}
Answer 1

Поскольку массив заполняется остатками по модулю, нужно посмотреть, что даёт свойство модульного умножения. Например, для квадратичного члена

(a * x * x) mod M = ((a mod M) * (x mod M) * (x mod M)) mod M 

Из этого следует, что остатки будут повторяться через каждые М чисел, и достаточно хранить M результатов. А надо ли хранить?

Для числа N = q * M + r: N-r остатков будет повторяться q раз, а к остатков будет повторяться q+1 раз.

Таки с образом, определяем для данного N параметры q и r, A[1743] инициируем нулями, затем делаем r шагов вычисления остатков по формуле, складывая единицы в A[остаток]. Затем считаем сумму, пока она не превысит k- идём по списку, добавляя q + A[i] к сумме.

Пример для (7*x+3) mod 5, N=8, K=5

значения для x=1,2,3...  10  17  24  31  38  45  52  59
остатки                   0  2   4   1   3   0   2   4 
  0 1 2 3 4  //индексы A[i]
  --------------
  1 1 1 1 1   //это не считаем, а подразумеваем
  1   1   1   //посчитали 3 остатка (8 mod 5)   
  2 3 5       //сложили, пока не набралось k=5 

Ответ - 2 (индекс, на котором накопили k=5)

проверяем: на 5 месте в сортированном списке остатков 0,0,1,2,2,3,4,4 идёт 2

Answer 2

Если имеется в виду k-тый локальный минимум:

function calc(n, k, showArray) { 
  var a = [1743]; 
  for (var i = 1; i <= n; i++) { 
    a[i] = (132 * (i * i * i) + 77 * (i * i) + 1345 * i + 1577) % 1743; 
  } 
  a[a.length] = 1743; 
  
  if (showArray)      
    console.log(JSON.stringify(a)); 
 
  var minCounter = 0; 
  for (var i = 1; i < a.length - 1; i++) { 
    if (a[i] < a[i - 1] && a[i] < a[i + 1]) { 
      if (++minCounter == k) { 
        return { index: i, value: a[i] }; 
      } 
    } 
  } 
} 
 
for (var i = 1; i <= 5; i++) { 
  console.log(10, i, JSON.stringify(calc(10, i, i == 1))); 
} 
console.log("for @pavel:", 4000000, 1234567, JSON.stringify(calc(4000000, 1234567)));

Как упражнение для читателя, оставлена задача оптимизации: совмещение двух циклов в один и выход из функции без вычисления всех n элементов массива.

Да, еще не учтен случай, когда минимум представляет собой площадку из нескольких точек.

Код становится слишком длинным, чтобы уместиться на полях этой книги.

Спокойствие. Те, кому свербит голосовать "против" из-за метки с++ в вопросе, - голосуйте, я не боюсь ).

...
Бейте четыре-десять,
Не жалейте огня!
К.Симонов "Сын артиллериста"
READ ALSO
Как работает vector?

Как работает vector?

Почему пример ниже выводит 6?

143
Сделать return массива

Сделать return массива

Не получается вернуть массив через функциюЯ создал функцию, которая создает массив и заполняет все его элементы двойками, но не могу вернуть...

159
Qt5 кроскомпиляция из под Windows в ARM

Qt5 кроскомпиляция из под Windows в ARM

Пытаюсь настроить Qt Creator (qt510

137