Problem Statement

 

There is an integer sequence <var>A</var> of length <var>N</var>.

Find the number of the pairs of integers <var>l</var> and <var>r</var> (<var>1≤lrN</var>) that satisfy the following condition:

  • <var>Al xor Al+1 xor … xor Ar=Al + Al+1 + … + Ar</var>

Here, <var>xor</var> denotes the bitwise exclusive OR.

 

Definition of XOR

 

Constraints

 

  • <var>1≤N≤2×105</var>
  • <var>0≤Ai<220</var>
  • All values in input are integers.

Input

 

Input is given from Standard Input in the following format:

<var>N</var>
<var>A1</var> <var>A2</var> <var>…</var> <var>AN</var>

Output

 

Print the number of the pairs of integers <var>l</var> and <var>r</var> (<var>1≤lrN</var>) that satisfy the condition.

Sample Input 1

 

4
2 5 4 6

Sample Output 1

 

5

<var>(l,r)=(1,1),(2,2),(3,3),(4,4)</var> clearly satisfy the condition. <var>(l,r)=(1,2)</var> also satisfies the condition, since <var>A1 xor A2=A1 + A2=7</var>. There are no other pairs that satisfy the condition, so the answer is <var>5</var>.

Sample Input 2

 

9
0 0 0 0 0 0 0 0 0

Sample Output 2

 

45

Sample Input 3

 

19
885 8 1 128 83 32 256 206 639 16 4 128 689 32 8 64 885 969 1

Sample Output 3

 

37

题意:
给你一个含有N个整数的数组,
让你求出有多少对l和r,使之 a[l]+...+a[r] = a[l]^... ^a[r]
即让你找出有多少对l和r,使数组的l~r的前缀和和异或和相等。

思路:
我们知道这样的结论,
对于一个数组,他的异或前缀和有和sum前缀和类似的性质。
即我们用一个数组 prexor[i]来维护从1~i数组的异或值,那么 l~r的异或值可以表示为
prexor[r]^prexor[l-1]

并且异或和sum和有这样的性质,
即如果l~r 数组 a[l]~a[r] 的sum和与a[l]^……^a[r]的异或值不同时,那么l与任意一个r以及r之后的i。
不会满足 l到i的sum和与异或和相同 。因为前一会有不满足的情况,后继的数组无论如何也不可能满足。
那么我们来看本题,
我们就可以通过上面的这个性质和利用双指针的常用套路方法:
对于每一个l,求出使之使其满足sum和与异或和相等的最右边的r。
那么以l为左端点的pair个数就是 r-l+1个
,然后我们把 l向右移动一位,同时删除 a[l]对sum和以及异或和的贡献。
然后对于新的l,我们只需要从上一个状态的r继续向后判定是否符合即可。(因为l~r满足的话,l+1~r一定也满足)
直至l大于n的时候跳出操作,输出答案即可。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int a[maxn];
int n;
ll ans = 0ll;

int main()
{
    //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
    //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
    gbtb;
    cin >> n;
    repd(i, 1, n)
    {
        cin >> a[i];
    }
//    ans=n;
    ll sum = 0ll;
    ll xo = 0ll;
    int l = 1;
    int r = 0;
    ll cnt = 0ll;
    while (1)
    {
        while (r < n && sum + a[r + 1] == (xo ^ a[r + 1]))
        {
            r++;
            sum += a[r];
            xo ^= a[r];
        }
        cnt = r - l + 1;
//        ans+=(cnt*(cnt+1))/2;
        ans += cnt;
        sum -= a[l];
        xo ^= a[l++];
        if (l == n + 1)
        {
            break;
        }
    }

    cout << ans << endl;

    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}