问题描述:
解题思路:
官方:
我的总结:
利用双指针遍历每个区间并判断是否符合条件:若一个区间符合条件则该区间在其左端点不变的情况下的每一个子区间都符合条件,相反若一个区间内左端点固定情况下有一个以其左端点为始的子区间不符合条件,则该区间不符合条件。因此可以先找到每一个左端点(即遍历完所有元素)固定情况下最远的右端点,(右端点减左端点)得出以该左端点为始有几个符合的区间,依次累加得总数及答案。
判断异或和等于算术和:算术运算没有进位时(二进制)。
注意点:
1.答案数据范围可能超过int,需要开long long。
2.遍历的条件是l<n, r <n。不是l < r。
3.左、右指针从第一个元素开始。
4.因为r(右指针)每一次循环都增加,循环依次减少,所以该程序为O(n)。
题解:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
int a[N];
using ll = long long;
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;cin >> n;
for(int i = 0; i < n; i++)cin >> a[i];
ll ans = 0;
int l = 0, r = 0, res = 0;
while(l < n){
while(r < n && ((res ^ a[r]) == (res + a[r]))) // (res ^ a[r]) == (res + a[r])判断符合条件
{
res ^= a[r]; // res:遍历的区间的异或和。
r++;
}
ans += r - l; // r -l:以该l为始的符合条件区间数
res ^= a[l]; // 异或相消律:不同的消去。此行的作用是res刷新为a[l]
l++;
}
cout << ans << '\n';
return 0;
}
知识点:
双指针,二分查找,异或和与算术和,进位