Codeforces1609C Análisis de mercado complejo (pensamiento)

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;
}

FIN

Supongo que te gusta

Origin blog.csdn.net/weixin_45799835/article/details/121637148
Recomendado
Clasificación