給出n和n個數,求異或和為0的子段個數
傳送門
設a[i]為輸入的數
b[i]為異或前綴和
b[i] = a[1] ^ a[2] ^ ... ^ a[i - 1] ^ a[i]
已知一個數x^y = 0當且僅當x == y時成立
那么對於一段[1,r]來說,異或前綴和為b[r],那么如果想要以r為異或為0的子段的右半部分,那么只需要前面出現過一個數b[i] == b[r],那么[i + 1,r]這一段異或和為0
就比如
對於\(x_{1},x_{2},x_{3} ... x_{r}\),如果想要找到一段區間[i,r]使得其區間異或和為0,設\(x_{1},x_{2},x_{3}...x_{j}\)的異或和為\(b[j]\)那么如果b[j] == b[r],也就是說b[j] ^ b[j+1,r] = b[r]而只有x ^ y == x當且僅當y = 0時成立。
那么只需要前綴異或和+map維護即可
#include <iostream>
#include <map>
#define ll long long
using namespace std;
const int maxn = 2e5 + 5;
std::map<ll, ll> mp;
ll a[maxn],b[maxn];
int main(){
int n;
cin >> n;
ll ans = 0;
for(int i = 1; i <= n; i++){
cin >> a[i];
b[i] = a[i] ^ b[i - 1];
if(b[i] == 0)ans++;
ans += mp[b[i]];
mp[b[i]]++;
cout << ans << endl;
}
cout << ans << endl;
return 0;
}
