Оптимизация алгоритма "Забавная игра"

Помогите, пожалуйста, оптимизировать алгоритм по времени выполнения. Признаюсь, переписал его с питона, потому что мой выполнялся ещё дольше. Мне кажется нужно концептуально поменять решение. Вот задание:

Забавная игра

Вы с друзьями играете в следующую игру. Друзья пишут на доске подряд N натуральных чисел. Ваша задача — найти как можно больше подряд идущих чисел, которые бы делились на одно и то же число, большее 1. Так как вручную искать ответ сложно, вы решили написать программу, которая сделает работу за вас.

Входные данные

В первой строке входных данных задано число N(1 ≤ N ≤ 100000). Во второй строке записано через пробел N целых чисел A1...AN(1 ≤ Ai ≤ 1000, 1 ≤ i ≤ N). Это те самые числа, которые написали ваши друзья. Они даны в том же порядке, в котором они расположены на доске.

Выходные данные

Ваша программа должна вывести одно целое число — наибольшее количество подряд идущих чисел заданной последовательности, которые бы делились на одно и то же натуральное число, большее 1.

Пример: Ввод 3 6 10 15 Вывод 2

Моя программа:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <deque>
#include <iterator>

using namespace std;

using lli = long long;
using lld = long double;
using ulli = unsigned long long;
using usi = unsigned short;

template <typename T2>
T2 gcd(T2 a, T2 b)
{
    if (a < b) swap(a, b);
    if (b == 0) return a;
    return gcd(b, a % b);
}

int main() {
    lli n, mx = 0, cur_g;
    cin >> n;
    vector <lli> a;
    lli x;
    for (lli i = 0; i < n; i++) {
        cin >> x;
        a.push_back(x);
    }

    for (lli i = 0; i < n; i++) {
        cur_g = a[i];
        if (n - i < mx) break;
        lli p = 0;
        for (lli j = i; j < n; j++) {
            cur_g = gcd(cur_g, a[j]);
            if (cur_g == 1) break;
            ++p;
            if (mx < p) mx = p;
        }
    }
    cout << mx;
}

Ответы (1 шт):

Автор решения: Harry

Ну, простое по мере чтения построение массива делимости на 11 простых чисел, укладывающихся в делители 1000. После чего 11 проходов по этим массивам. O(N), несмотря на 12 в сумме проходов :)

#include <iostream>
#include <iomanip>

using namespace std;

int p[11] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };

int v[11][100000] = {};

int main()
{
    int N;
    cin >> N;
    for(int i = 0; i < N; ++i)
    {
        int M;
        cin >> M;
        for(int j = 0; j < 11; ++j)
            if (M%p[j] == 0) v[j][i] = 1;
    }
    int M = 0;
    for(int j = 0; j < 11; ++j)
    {
        int K = 0;
        for(int i = 0; i < N; ++i)
            if (v[j][i] == 0)
            {
                if (M < K) { M = K; }
                K = 0;
            }
            else ++K;
        if (M < K) M = K;
    }

    cout << M;

}

благополучно проходит https://informatics.msk.ru/mod/statements/view.php?id=7847

→ Ссылка