Nasser's Prime Slices#12432

Nasser's Prime Slices (Editorial)

Problem Author:

Mohammad Nasser (MOAGEZA)

Prepared by:

Mohammad Nasser (MOAGEZA)

Edited by:

Hasan Saleh (MathModel)

Solution

General Idea:

First, precompute all primes up to 10^7 using the Sieve of Eratosthenes.

For a valid slicing to exist, the total number of primes in the array must be divisible by . If not, the answer is .

Otherwise, think of the problem as placing cut points between groups of exactly primes. Between consecutive groups of primes, there may be some non-prime elements. Each non-prime element in such a gap can either be in the left subarray or the right subarray, giving a free binary choice per gap element — so a gap of size contributes a multiplicative factor of g + 1 to the answer.

More precisely, sweep the array left to right, maintaining a count of primes seen so far in the current group and a counter for the number of ways to place the current cut:

  • When a non-prime is seen and \mathit{cnt} = k, increment (one more valid cut position).

  • When a prime is seen and \mathit{cnt} = k, multiply by , reset \mathit{check} = 1 and \mathit{cnt} = 0, then increment .

At the end, if the last group does not contain exactly primes, output . Otherwise output \mathit{ans} \bmod (10^9 + 7).

The solution runs in \mathcal{O}\!\left(A \log \log A + \sum n\right) time per test file, where A = 10^7 is the sieve bound and \sum n \le 2 \times 10^5 is the total input size across all test cases.

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int MAX = 1e7 + 1, mod = 1e9 + 7;
vector<bool> is_prime(MAX, true);

void sieve() {
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; i * i < MAX; i++)
        if (is_prime[i])
            for (int j = i * i; j < MAX; j += i)
                is_prime[j] = false;
}

void solve() {
    int n, k, cnt = 0, check = 1;
    cin >> n >> k;
    ll ans = 1;
    for (int i = 0; i < n; i++) {
        int x; cin >> x;
        if (!is_prime[x]) {
            if (cnt == k) check++;
        } else {
            if (cnt == k) {
                ans = ans * check % mod;
                check = 1; cnt = 0;
            }
            cnt++;
        }
    }
    if (cnt != k) { cout << 0; return; }
    cout << ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    sieve();
    int t; cin >> t;
    while (t--) { solve(); cout << '\n'; }
    return 0;
}