"EJOI2019" exclusive or orange

Topic Link

First come first two lemma
\ [a \ oplus a = 0
\\ 0 \ oplus a = a \] know after this lemma, we can look at samples
\ [a_2 \ oplus a_3 \ oplus a_4 \ oplus ( a_2 \ oplus a_3) \ oplus ( a_3 \ oplus a_4) \ oplus (a_2 \ oplus a_3 \ oplus a_4) = a_2 \ oplus a_2 \ oplus a_2 \ oplus a_3 \ oplus a_3 \ oplus a_3 \ oplus a_3 \ oplus a_4 \ oplus a_4 \ oplus a_4 \\ = a_2 \ oplus0
\ oplus a_4 = 2 \] means that we can some properties XOR, to optimize it

If \ (A \) number is an odd number contribution \ (A \) , if the \ (A \) number is an even number which is the contribution \ (0 \)

Push a few data can be found

If \ (l, r \) any number of different parity is an even number, the result is naturally \ (0 \)

If \ (l, r \) have the same parity, then only and (l, r \) \ number will be on location contribute parity

We can start to maintain two arrays next tree, a prefix or maintains exclusive odd bit and other maintenance XOR even bit prefix and

For an operation, the attention is not on \ (I \) bitwise XOR \ (J \) is the \ (I \) is modified to \ (J \) , according to the nature of our exclusive OR and exclusive first or \ ( a [i] \) in the exclusive-oR \ (J \) , or can be exclusive $ a [i] \ oplus j $

2 for the first operation determination Laid different parity, the parity for the same, we obtain a corresponding tree in the array \ (r, l-1 \ ) of a prefix and an exclusive OR, XOR look to

#include <bits/stdc++.h>
#define lowbit( x ) ( x & - x )
using namespace std;


const int N = 2e5 + 10;
int n , m , bit[2][N] , a[N];


inline int read()
{
    register int x = 0;
    register char ch = getchar();
    while( ch < '0' || ch > '9' ) ch = getchar();
    while( ch >= '0' && ch <= '9' )
    {
        x = ( x << 3 ) + ( x << 1 ) + ch - '0';
        ch = getchar();
    }
    return x;
}

inline void add( int val , int pos , int k )
{
    for( register int i  = pos ; i <= n ; bit[k][i] ^= val , i += lowbit( i ) );
}

inline int find( int pos , int k )
{
    register int res = 0;
    for( register int i = pos ; i >= 1 ; res ^= bit[k][i] , i -= lowbit( i ) );
    return res;
}

int main()
{
    n = read() , m = read();
    for( register int i = 1  ; i <= n ; a[i] = read() , add( a[i] , i , i & 1 ) ,  i ++ );
    for( register int i = 1 , op , l , r ; i <= m ; i ++ )
    {
        op = read() , l = read() , r = read();
        if( op == 1 ) add( a[l] ^ r , l , l & 1 ) , a[l] = r ;
        else printf( "%d\n" , ( ( l + r ) & 1 ) ? 0 : ( find( r , r & 1 ) ^ find( l - 1 , r & 1 ) ) );
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Mark-X/p/11688003.html