Tabla de contenido
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 n1≤L≤R≤n 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 300norte≤300 ;
Para 60 % 60\%60% de los casos de evaluación,n ≤ 5000 n \leq 5000norte≤5000 ;
Para todos los casos de evaluación, 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^51≤norte≤1 05,0 ≤ A yo ≤ 2 20 0 \leq A_i \leq 2^{20}0≤Ayo≤220 _
7. Enlace al título original
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)( 1≤yo≤r≤n ) , 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})ayo⊕ayo + 1⊕⋯⊕aj − 1⊕aj=( un1⊕a2⊕⋯aj)⊕( un1⊕a2⊕⋯⊕ayo − 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_jayo⊕ayo + 1⊕⋯⊕aj − 1⊕aj=Syo − 1⊕Sj
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 = 0∑202i×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)