每日一题 Xorto
链接戳这
题意:
给定一个长度为n的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为0。
思路:
由于区间异或和我们可以提前预处理前缀sum数组然后o(1)得到,我们可以先枚举右区间,然后由于两个不相交,我们要用个桶数组预处理出x-1之前某个相同区间异或值出现的次数,可以在for里面并排预处理完,x向前进一步说明x-1也进了一步,也就是说多出来的贡献就是以x-1为右端点的区间,我们只需要枚举左端点预处理出多出来的数就可以了。
感悟:
没想到可以先枚举左端点,思维还是老化了。
ac代码:
#include<bits/stdc++.h>
using namespace std;
const int N=300010;
int a[N];
int cnt[N];
int sum[N];
typedef long long ll;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]^a[i];
}
ll res=0;
for(int x=1;x<=n;x++)
{
for(int j=1;j<=x-1;j++)
cnt[sum[x-1]^sum[j-1]]++;
for(int y=x;y<=n;y++)
res+=cnt[sum[y]^sum[x-1]];
}
cout<<res<<endl;
return 0;
}
传音控股公司福利 360人发布
