C/C++ Grupo A Pregunta H de la 14ª Competición Provincial Copa Lanqiao - XOR y Sum (AC)

1. XOR y suma

1. Descripción del tema

Dada una matriz A i A_iAyo, encuentre la suma XOR de cada uno de sus subsegmentos y encuentre su suma. En otras palabras, para cada grupo que satisface 1 ≤ L ≤ R ≤ n 1 \leq L \leq R \leq n1LRn L, RL , RL ,R , encuentre elLLthL aRRSuma XOR de elementos R. Luego emita cada conjunto deL , RL, RL ,La suma de los resultados obtenidos por R.

2. Formato de entrada

La primera línea de entrada contiene un número entero nnnorte _

La segunda línea contiene nnn enterosA i A_iAyo, separados por un espacio entre enteros adyacentes.

3. Formato de salida

Muestra una línea que contiene un número entero que representa la respuesta.

4. Entrada de muestra

5
1 2 3 4 5

5. Salida de muestra

39

6. Rango de datos

Por 30% 30\%30% de los casos de evaluación,n ≤ 300 n \leq 300norte300 ;

Para 60 % 60\%60% de los casos de evaluación,n ≤ 5000 n \leq 5000norte5000 ;

Para todos los casos de evaluación, 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^51norte1 050 ≤ A yo ≤ 2 20 0 \leq A_i \leq 2^{20}0Ayo220 _

7. Enlace al título original

XOR y suma

2. Ideas para resolver problemas

Primero, enumere violentamente cada subintervalo [ l , r ] [l,r] según el significado de la pregunta[ yo ,r ] ( 1 ≤ l ≤ r ≤ norte ) (1\leq l \leq r \leq n)( 1yorn ) , la complejidad seráO ( n 2 ) O(n^2)O ( n2 ), no puede pasar esta pregunta, pero puede obtener un puntaje determinado.

Dado que se trata de una operación XOR y observando ai a_iayoEl rango de valores es [ 0 , 2 20 ] [0,2^{20}][ 0 ,220 ], no nos resulta difícil pensar el problema desde la perspectiva del "desmontaje". Suponga que para el i-ésimo ∈ [ 0 , 20 ] i \in[0,20]del bit binarioi[ 0 ,20 ] bits, hayxxLa suma XOR de los x subintervalos en este bit es1 11 , entonces la contribución de este bit a la respuesta es2 i × x 2^{i} \times x2i×x _ De esta manera, dividimos todo el gran problema en20 2020 subpreguntas, la matriz original es equivalente a ser dividida en 20 20por nosotros20 010101 matriz.

Para cada subpregunta, es decir, para cada 01 0101 , necesitamos averiguar cuántos sub-arreglos cuya suma XOR es1 11 , que es encontrar el xxmencionado anteriormentex _ Podemos resolver este problema con el prefijo XOR. Establecer aquí01 0101 matriz esaauna matriz, configuramos otroSSS pares,S i S_iSyosignifica aauna matriz antes deii¿Cuál es la suma XOR de i elementos? Según la naturaleza de la operación XOR:

ai ⊕ ai + 1 ⊕ ⋯ ⊕ aj − 1 ⊕ aj = ( un 1 ⊕ un 2 ⊕ ⋯ aj ) ⊕ ( un 1 ⊕ un 2 ⊕ ⋯ ⊕ ai − 1 ) a_i \oplus a_{i+1} \oplus \ cdots \oplus a_{j-1} \oplus a_j=(a_1 \oplus a_2 \oplus \cdots a_j) \oplus (a_1 \oplus a_2 \oplus \cdots \oplus a_{i-1})ayoayo + 1aj 1aj=( un1a2aj)( un1a2ayo 1)

Aplique la fórmula anterior a SSS se reemplaza por:

ai ⊕ ai + 1 ⊕ ⋯ ⊕ aj − 1 ⊕ aj = S yo − 1 ⊕ S j a_i \oplus a_{i+1} \oplus \cdots \oplus a_{j-1} \oplus a_j=S_{i- 1} \oplus S_jayoayo + 1aj 1aj=Syo 1Sj

Si quieres que el lado izquierdo de la ecuación sea igual a 1 11 , lo que significaS i − 1 ≠ S j S_{i-1} \ne S_jSyo 1=Sj

De acuerdo con el análisis anterior, podemos enumerar cada 01 0101 El prefijo XOR matrizSSS , cuando enumeramos aS j S_jSj, solo necesitamos considerar cuántos S i S_i antesSyoA diferencia de él, los diferentes números son iguales a aj a_jajfinal y suma XOR es 1 1El número de subarreglos de 1 , podemos usar la tabla hash para realizar la función de contar el número.

De esta manera podemos correr cerca de O ( n ) O(n)La complejidad de O ( n ) cuenta cada01 0101 Subintervalo de matriz XOR es1 1El número de 1 , establecemos elii01 01 de i dígitos binarios01 Subintervalo de matriz XOR es1 1El número de 1 esbi b_ibyo, la respuesta final es:

∑ yo = 0 20 2 yo × bi \sum_{i=0}^{20} 2^{i} \times b_iyo = 0202i×byo

Complejidad del tiempo: O ( 20 × n ) O(20 \times n)O ( 20×n )

3. Código_AC

  • C++
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;

int n;
int a[N][25];
int main()
{
    
    
	ios_base :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i) {
    
    
		int x;
		cin >> x;
		for (int j = 0; j <= 20; ++j) {
    
    
			a[i][j] = (x >> j) & 1;
			a[i][j] ^= a[i - 1][j];
		}
	}
	LL ans = 0;
	for (int j = 0; j <= 20; ++j) {
    
    
		map<int, int> m;
		m[0]++;
		for (int i = 1; i <= n; ++i) {
    
    
			int x = m[a[i][j] ^ 1];
			ans += 1LL * (1 << j) * x;
			m[a[i][j]]++;
		}
	}
	cout << ans << '\n';
	return 0;
}
  • Java
import java.util.*;

public class Main {
    
    
    static final int N = 100010;

    public static void main(String[] args) {
    
    
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[][] a = new int[N][25];
        for (int i = 1; i <= n; ++i) {
    
    
            int x = scan.nextInt();
            for (int j = 0; j <= 20; ++j) {
    
    
                a[i][j] = (x >> j) & 1;
                a[i][j] ^= a[i - 1][j];
            }
        }
        long ans = 0;
        for (int j = 0; j <= 20; ++j) {
    
    
            Map<Integer, Integer> m = new HashMap<>();
            m.put(0, 1);
            for (int i = 1; i <= n; ++i) {
    
    
                int x = m.getOrDefault(a[i][j] ^ 1, 0);
                ans += (1L << j) * x;
                m.put(a[i][j], m.getOrDefault(a[i][j], 0) + 1);
            }
        }
        System.out.println(ans);
    }
}
  • Pitón
n = int(input())
N = 100010
a = [[0] * 25 for _ in range(N)]
b = list(map(int, input().split()))
for i in range(1, n + 1):
    x = b[i-1]
    for j in range(21, -1, -1):
        a[i][j] = (x >> j) & 1
        a[i][j] ^= a[i - 1][j]
ans = 0
for j in range(21, -1, -1):
    m = {
    
    0: 1}
    for i in range(1, n + 1):
        x = m.get(a[i][j] ^ 1, 0)
        ans += (1 << j) * x
        m[a[i][j]] = m.get(a[i][j], 0) + 1
print(ans)

Supongo que te gusta

Origin blog.csdn.net/m0_57487901/article/details/131712490
Recomendado
Clasificación