[51nod1577] número XOR

Titulo

  Haga clic aquí para ver el tema.

Análisis

  La siguiente configuración es \ (k = \ lfloor \ log_2 (\ max a) \ rfloor \) .
  El problema de los números XOR puede manejarse naturalmente con una base lineal, es decir, si se puede insertar en una base lineal, significa que este número no se puede resolver.
  Entonces, tenemos un árbol de segmentos de línea o un método para mantener la base lineal del intervalo, el tiempo es \ (O (k ^ 2nlog_2n) \) .
  ... Olvídalo.
  Considere mantener una base lineal \ (B_i \) para cada punto . Se mantiene la base lineal "óptima" de \ ([1, i] \) . "Óptimo" significa que los elementos en la base lineal son los últimos en la secuencia original.
  Al consultar \ ([l, r] \) , solo podemos usar el elemento en la posición \ (\ ge l \) en \ (B_r \) , podemos encontrar que una base tan lineal puede usar los elementos en el interior como máximo, Por lo tanto, es óptimo.   Considere construir \ (B \) recursivamente . Empujamos de \ (B_ {i-1} \) a \ (B_i \) : saque los elementos en \ (B_ {i-1} \) y trabaje junto con \ (a_i \) según la posición de grande a pequeño Insertar en \ (B_i \) . Se puede encontrar que la base lineal construida de esta manera puede estar compuesta
\ ([1, i] \) , y definitivamente es el mejor.
  De acuerdo con este método de construcción, también podemos encontrar que los elementos de la base lineal utilizados al consultar \ ([l, r] \) deben ser capaces de completar el número de \ ([l, r] \) . Los elementos cuya posición es menor que \ (l \) no se eliminan, lo que significa que se pueden improvisar sin la necesidad de \ ([l, r] \) .
  Esta recursividad es \ (O (k ^ 2n) \) , que todavía es muy lenta, y continúa optimizándose.
  \ (B_i \) a \ (B_ {i-1} \) obviamente solo tiene un \ (a_i \) más , pero gastamos \ (O (k ^ 2) \) , que obviamente no es muy rentable.
  Si \ (a_i \) se puede insertar directamente en \ (B_ {i-1} \) , podemos usar \ (B_ {i-1} \) después de insertar \ (a_i \) como \ (B_i \) .
  De lo contrario, encontramos el elemento que entra en conflicto con el valor insertado . Si la posición del valor insertado es mejor que el elemento original, debemos reemplazar el valor insertado con el elemento en la posición actual y dejar que el elemento original continúe insertándose como el valor insertado; de lo contrario, no intercambiaremos y continuaremos con el siguiente paso.
  Se puede encontrar que el \ (B_i \) obtenido por este reemplazo es definitivamente el mejor. Debido a la sustitución de los elementos serán todavía estar fuera de la inserción, y para \ (J \) de los elementos originales de la broca, que \ (J \) ningún valor bits o más, y por lo tanto puede ser un grupo lineal Couchu \ ([1, i ] \) Elementos. Entonces obtenemos el óptimo legal \ (B_i \) . El tiempo es \ (O (kn) \) .

Código

#include <cstdio>

const int MAXN = 5e5 + 1, MAXLOG = 31;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

template<typename _T>
void swapp( _T &x, _T &y )
{
	_T t = x; x = y, y = t;
}

struct node
{
	int val, pos;
	node() {}
	node( const int V, const int P ) { val = V, pos = P; }
	bool operator > ( const node & b ) { return pos > b.pos; }
};

node base[MAXN][MAXLOG];

int a[MAXN];
int N;

int main()
{
	read( N );
	for( int i = 1 ; i <= N ; i ++ ) read( a[i] );
	for( int i = 1 ; i <= N ; i ++ )
	{
		node cur = node( a[i], i );
		for( int j = 29 ; ~ j ; j -- ) base[i][j] = base[i - 1][j];
		for( int j = 29 ; ~ j ; j -- )
			if( ( cur.val >> j ) & 1 )
			{
				if( ! base[i][j].val ) { base[i][j] = cur; break; }
				if( base[i][j].pos < cur.pos ) swapp( base[i][j], cur );
				cur.val ^= base[i][j].val;
			}
	}
	int T, l, r, v;
	read( T );
	while( T -- )
	{
		read( l ), read( r ), read( v );
		for( int j = 29 ; ~ j ; j -- )
			if( ( v >> j ) & 1 )
			{
				if( ! base[r][j].val || base[r][j].pos < l ) break;
				v ^= base[r][j].val;
			}
		puts( v ? "Budexin" : "Koyi" );
	}
	return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/crashed/p/12686623.html
Recomendado
Clasificación