题目大意
给定一个序列,q个查询
查询(l,r)内 异或值=0 的最小区间
题目分析
考虑对序列求一个前缀异或和
那么 每个点找到与自己相同的最近的点的位置,就是每个点作为右端点 =0 的最小区间。
所有的查询区间按照右端点排序
然后我们枚举1,n所有点,在线段树 该店对应左端点的位置插入这个区间长度。
对于所有右端点为i的询问 查询(l,r)区间内的最小值即可
代码详解
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn =6e5+50;
const int maxm =2e6+60;
int n,q;
struct node
{
int ans=inf;
int id;
int l,r;
}t[maxn];
int a[maxm];
int pre[maxm];
int last[maxm];
int le[maxm];
bool cmp(node a,node b)
{
if(a.r==b.r) return a.l>b.l;
return a.r<b.r;
}
struct Node
{
//int data;
int l,r;
int mn;
}tree[maxn*4];
void pushup(int root)
{
tree[root].mn = min(tree[root*2].mn,tree[root*2+1].mn);
}
void build(int root,int l,int r)
{
if(r<l)return;
tree[root].l = l; tree[root].r = r;
if(l==r)
{
tree[root].mn = inf;
return;
}
int mid = (l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
pushup(root);
}
void update(int root,int k,int val)
{
int l = tree[root].l;
int r = tree[root].r;
if(l==r)
{
tree[root].mn =val;
return;
}
int mid = (l+r)/2;
if(mid<k) update(root*2+1,k,val);
else update(root*2,k,val);
pushup(root);
//cout<<tree[root].mn
}
int query(int root,int st,int ed)
{
int l = tree[root].l;
int r = tree[root].r;
// cout<<l<<" "<<r<<" "<<tree[root].mn<<endl;
if(st<=l&&ed>=r) return tree[root].mn;
else if(st>r||ed<l) return inf;
int ans = inf;
ans = min(ans,query(root*2,st,ed));
ans = min(ans,query(root*2+1,st,ed));
return ans;
// if(tree[root].l == tree[root].r)
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
pre[0] = 0;
memset(last,-1,sizeof(last));
last[0] = 0;
for(int i=1;i<=n;i++)
{
pre[i]=pre[i-1]^a[i];
le[i] = last[pre[i]];
last[pre[i]] = i;
}
for(int i=1;i<=q;i++)
{
scanf("%d%d",&t[i].l,&t[i].r);
t[i].id= i;
}
sort(t+1,t+1+q,cmp);
build(1,1,n);
for(int i=1;i<=q;i++)
{
int r = t[i].r;
if(le[r]!=-1)
{
update(1,le[r]+1,r-le[r]);
}
t[i].ans = query(1,t[i].l,t[i].r);
}
sort(t+1,t+1+q,cmp2);
for(int i=1;i<=q;i++)
{
if(t[i].ans<maxm)
printf("%d\n",t[i].ans);
else printf("-1\n");
}
return 0;
}