Xorto
时间限制:2秒 空间限制:32768K
题目描述
给定一个长度为n的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为0。
输入描述:
第一行一个数n表示数组长度;
第二行n个整数表示数组;
1<=n<=1000,0<=数组元素<100000。
输出描述:
一行一个整数表示答案。
示例1
输入
3
0 0 0
输出
5
说明
([1,1],[2,2]),([1,1],[3,3]),([1,1],[2,3]),([1,2],[3,3]),([2,2],[3,3])
解题思路:发现所有的区间可以在n*n的时间复杂度内求出来,又发现,他要求得区间符合亦或值是得相等的性质,所以我们可以对区间先按照值排一下序,然后按照左端点排序,之后对于每一个区间,发现是具有单点性的,时间复杂度是O(n^2log(n^2))的,是符合题目目要求的,所以就可以写了。
code:
#include<stdio.h>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1010;
struct node
{
int x,y;
ll zhi;
int biao;
} b[maxn*maxn];
map<ll,int>MAP;
ll a[maxn];
inline bool cmp(node a,node b)
{
if(a.zhi!=b.zhi)
return a.zhi<b.zhi;
return a.x<b.x;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
a[i]^=a[i-1];
}
if(n==1)
{
printf("0\n");
return 0;
}
int k=0;
for(int i=1; i<=n; i++)
for(int j=i; j<=n; j++)
{
b[k].zhi=a[j]^a[i-1];
b[k].x=i;
b[k++].y=j;
}
sort(b,b+k,cmp);
ll ans=0;
int l=0,r=0;
while(r<k)
{
for(int i=l+1; i<k; i++)
{
if(b[i].zhi!=b[i-1].zhi)
break;
else
r++;
}
for(int kk=l; kk<r; kk++)
{
int ll=kk,rr=r;
while(ll<rr)
{
int mid=(ll+rr)>>1;
if(b[mid].x<=b[kk].y)
{
ll=mid+1;
}
else
{
rr=mid;
}
}
if(b[rr].zhi==b[kk].zhi)
{
if(b[rr].x>b[kk].y)
ans+=r-rr+1;
}
}
r++;
l=r;
}
printf("%lld\n",ans);
}