Enlace temático: Análisis de mercado complejo
Idea general
dada una longitud de nnsecuenciaaa de na .Dado el intervalokkk _
Fijo: f (i, j) f (i, j)f ( yo ,j ) significa desde la posicióniicomienzo, elemento seleccionadoai, ai + k, ai + 2 k, .., ai + jk a_i, a_ {i + k}, a_ {i + 2k}, ..., a_ {i + jk }unyo,unyo + k,unyo + 2 k,. . . ,unyo + jk _, por lo que el producto de todos los elementos seleccionados es un número primo .
Pregunta: Para i , j ∈ [ 1 , n ] i, j \in [1, n]yo ,j∈[ 1 ,n ] Condicional( i , j )(i, j)( yo ,j ) cuantos pares
Ideas para resolver problemas
pensando
El conjunto que consideramos que contribuye a la respuesta debe ser: un número primo y un número de 1s .
Entonces podemos enumerar cada posición principal considerando la contribución a la respuesta.
Para cada posición de número primo , la recorremos hacia la izquierda y hacia la derecha para encontrar el 1 1 consecutivo en los lados izquierdo y derechoEl número de 1 izquierda, derecha izquierda, derechaizquierda , _ _ _correcto _ _ _ _ _
Entonces la contribución de la posición actual a la respuesta es: ( izquierda + 1 ) ∗ ( derecha + 1 ) − 1 (izquierda + 1) * (derecha + 1) - 1( izquierda _ _ _+1 )∗( correcto _ _ _ _+1 )−1 .
menos 1 11 es longitud1 1El intervalo de 1 (solo se elige el número primo en sí).
código de CA
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1E6 + 10;
/* 欧拉筛模版 */
bool vis[N];
int prime[N], ind;
void init(int n = N - 5) {
vis[1] = 1; // 注意vis[1]是否需要置为1
for (int i = 2; i <= n; ++i) {
if (!vis[i]) prime[++ind] = i;
for (int j = 1; prime[j] * i <= n; ++j) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
}
}
}
int a[N];
int main()
{
init();
int t; cin >> t;
while (t--) {
int n, m; scanf("%d %d", &n, &m);
rep(i, n) scanf("%d", &a[i]);
ll res = 0;
rep(i, n) {
if (vis[a[i]]) continue;
int left = 1, right = 1;
for (int j = i - m; j >= 1; j -= m) {
if (a[j] == 1) left++;
else break;
}
for (int j = i + m; j <= n; j += m) {
if (a[j] == 1) right++;
else break;
}
res += 1ll * left * right - 1;
}
printf("%lld\n", res);
}
return 0;
}