题意:
给一个长度为N的数组
然后求满足 他们的异或和 加和相等的区间
题解:
我们发现,一旦两个数字有一位都是1,他们会变成0,所以这时候肯定就少了值,换句话说,两个数异或的最大值,是两个数的加和
所以枚举每个位置,然后向前异或,因为,所以每次最多20次向前
复杂度20*n,也就是log(ai)*n
#include<cstring> #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<ctime> #define ll long long using namespace std; const int maxn=200005; int n,a[maxn],lef[maxn]; ll ans=0; int main(){ scanf("%d",&n); for(int i=1,las=0;i<=n;i++){ scanf("%d",a+i),lef[i]=las; if(a[i]) las=i; } for(int i=1,now,j;i<=n;i++){ now=a[i]; for(j=lef[i];j;now^=a[j],j=lef[j]) if(now&a[j]) break; ans+=(ll)(i-j); } cout<<ans<<endl; return 0; }
AtCoder Regular Contest 098 D - Xor Sum 2
原文:https://www.cnblogs.com/acmLLF/p/13642154.html