AtCoder Regular Contest 098 D

 题意:

给一个长度为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;
}
原文地址:https://www.cnblogs.com/acmLLF/p/13642154.html