AT4142
[ARC098B] Xor Sum 2
被迫害到了这种程度。。
然后是一个考察对
异或和与和相等的一个很重要的条件是不进位。简单来说,如果在加法中产生了进位,异或和就绝对不可能与和的数值相等。再换句话说,不同数字异或和上的每一位,有且仅能有 1 个 1 存在,不然必然会在加法中产生进位。
那么再换句话说,如果异或和目前已经与和不相等了,就说明加法中已经产生了进位,那么这个异或和与和就永远不可能相等了。从严谨一些的角度理解,设异或和为
所以说可以直接用一个双指针操作。
时间复杂度
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2e5;
ll n,ans;
ll a[N+5],c[N+5],c_[N+5];
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
return ret*f;
}
void write(ll x) {
static char buf[22];static ll len=-1;
if(x>=0) {
do{buf[++len]=x%10+48;x/=10;}while(x);
}
else {
putchar('-');
do{buf[++len]=-(x%10)+48;x/=10;}while(x);
}
while(len>=0) putchar(buf[len--]);
}
int main() {
n=read();
for(ll i=1,j=1;i<=n&&j<=n;i++) {
a[i]=read();
c[i]=c[i-1]^a[i];
c_[i]=c_[i-1]+a[i];
while((c[j-1]^c[i])!=c_[i]-c_[j-1]) j++;
ans+=i-j+1;
}
write(ans);
return 0;
}