CF1592E Bored Bakry(二进制+前缀异或和)
生活随笔
收集整理的這篇文章主要介紹了
CF1592E Bored Bakry(二进制+前缀异或和)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CF1592E Bored Bakry
- description
- solution
- code
description
題目鏈接
solution
and\text{and}and如果第iii位為111,意味著區間內每個數的第iii位都是111
xor\text{xor}xor如果第iii位為111,意味著區間內有奇數個第iii位為111
這種涉及二進制操作的一般都考慮拆位單獨處理
從高到低位枚舉,在第i位決出勝負
意思是,區間前i?1i-1i?1位and\text{and}and和xor\text{xor}xor的結果一樣,在第iii位時,and\text{and}and為111,xor\text{xor}xor為000
那么就需要滿足一些判句
- 區間長度為偶數,且每個數第iii位都為111
- 前i?1i-1i?1的每一位,區間中為111的個數都必須是偶數
不可能出現
xor:1 1 0 0
and:1 1 0 1
這種數據,因為由and位是1,xor位是0的某個i可以得到,這一定是個偶數長度的區間
那么前面兩個and都為1的時候,xor一定不為1
可以用前綴異或和來判定區間111的個數都必須是偶數
- 具體而言:[1,x][1,x][1,x]的異或和為vvv,找到上一個異或和為vvv的yyy,那么(y,x](y,x](y,x]區間內的前幾位每一位區間個數都是偶數了
通過這個同時來判斷區間內每個數的第iii位是否都是111,定義Andx:And_x:Andx?: 前xxx個數中第iii位為111的個數
判斷Andx?Andy=x?yAnd_x-And_y=x-yAndx??Andy?=x?y是否成立即可
code
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define maxn 1000005 int n, ans; int a[maxn], And[maxn], Xor[maxn], lst[maxn];int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) scanf( "%d", &a[i] );for( int j = 19;~ j;j -- ) {for( int i = 1;i <= n;i ++ ) {And[i] = And[i - 1] + ( a[i] >> j & 1 );Xor[i] ^= ( ( And[i] & 1 ) << j );}memset( lst, -1, sizeof( lst ) );lst[0] = 0;for( int i = 1;i <= n;i ++ ) {if( lst[Xor[i]] == -1 ) lst[Xor[i]] = i;else {int k = lst[Xor[i]];if( And[i] - And[k] == i - k ) ans = max( ans, i - k );else lst[Xor[i]] = i;}}}printf( "%d\n", ans );return 0; }總結
以上是生活随笔為你收集整理的CF1592E Bored Bakry(二进制+前缀异或和)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XFTP无法传输_xftp软件,比xft
- 下一篇: CF1580C Train Mainte