老瞎眼 pk 小鲜肉
题目描述
老瞎眼有一个长度为 n 的数组 a,为了为难小鲜肉,他准备了 Q 次询问,每次给出一个区间[L,R],他让小鲜肉寻 找一对 l,r 使L<=l<=r<=R 且 a[l] ^ a[l+1] ^ a[l+2]…^a[r]=0,老瞎眼只让他回答r-l+1 最小是多少,若没有符合条件的 l,r 输出”-1”。
输入描述:
第一行输入 n,Q。
第二行输入 n 个数,表示 a 数组。
接下来 Q 行,每行输入 L,R。
1<=n,Q<=500000,0<=a[i]<=1000000,1<=L<=R<=n
输出描述:
若有解,输出 r-l+1 最小是多少。
否则输出“-1”。
输入
4 2
2 1 3 3
1 2
1 3
输出
-1
3
思维+线段树;
1.我们要维护 a[] 的异或前缀和,因为只要异或前缀和,找到某两个位置的异或前缀和相等,那么这两个位置之间的数异或就为0;
2.知道第一点,这道题就演变成了求最近的相等的数;可以先把要求的区间按r从小到大排序,然后依次求区间里的数是否有相等的数;
3.这道就变成了一道单点修改+区间查询的线段树;last数组表示这个数之前出现的位置,知道了这个只要把last[i]+1这个值单点修改为区间宽度就行;线段树树区间维护最小值;
4.last切记开到200万;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
#define N 500100
#define M 2000010
using namespace std;
int a[N],last[M],s[N];
int x,y,sum;
struct Nod{
int l,r,post;
}dian[N];
bool cmp(Nod p,Nod q){
return p.r<q.r;
}
struct Node{
int l,r,w;
}tree[N<<2];
inline void build(int k,int ll,int rr){
tree[k].l=ll,tree[k].r=rr,tree[k].w=2e9;
if(ll==rr) return;
int mid=(ll+rr)>>1;
build(lson,ll,mid);
build(rson,mid+1,rr);
}
inline void update(int k){
if(tree[k].l==tree[k].r){
tree[k].w=y;
return;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(x<=mid) update(lson);
else update(rson);
tree[k].w=min(tree[lson].w,tree[rson].w);
}
inline int ask(int k){
if(tree[k].l>=x&&tree[k].r<=y){
return tree[k].w;
}
int mid=(tree[k].l+tree[k].r)>>1;
int re=2e9;
if(x<=mid) re=min(re,ask(lson));
if(y>mid) re=min(re,ask(rson));
return re;
}
int main(){
int n,q;
scanf("%d%d",&n,&q);
build(1,1,n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]^=a[i-1];
}
memset(last,-1,sizeof(last));
last[0]=0;
for(int i=1;i<=q;i++){
scanf("%d%d",&dian[i].l,&dian[i].r);
dian[i].post=i;
}
sort(dian+1,dian+q+1,cmp);//按r从小到大排
int i=1;
for(int j=1;j<=q;j++){//q个区间
for(;i<=dian[j].r;i++){//这个i不是从1开始,而是一直往后走
if(last[a[i]]!=-1){
x=last[a[i]]+1;
y=i-last[a[i]];
//cout<<y<<endl;
update(1);
}
last[a[i]]=i;
}
x=dian[j].l,y=dian[j].r;
sum=ask(1);
if(sum!=2e9) s[dian[j].post]=sum;
else s[dian[j].post]=-1;
}
for(int i=1;i<=q;i++) printf("%d\n",s[i]);
return 0;
}