牛客练习赛53 (E 老瞎眼 pk 小鲜肉) 线段树+离线
考试的时候切的,类似HH的项链~
code:
#include <bits/stdc++.h> #define ll long long #define M 500003 #define N 2000005 #define inf 100000000 #define lson now<<1 #define rson now<<1|1 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,q,m; int output[M],lst[N],A[M],Min[M<<2]; struct query { int l,r,id; }pp[M]; bool cmp(query a,query b) { return a.r<b.r; } void build(int l,int r,int now) { if(l==r) { Min[now]=inf; return; } int mid=(l+r)>>1; if(l<=mid) build(l,mid,lson); if(r>mid) build(mid+1,r,rson); Min[now]=inf; } void update(int l,int r,int now,int p,int v) { if(l==r) { Min[now]=v; return; } int mid=(l+r)>>1; if(p<=mid) update(l,mid,lson,p,v); else update(mid+1,r,rson,p,v); Min[now]=Min[lson]; if(r>mid) Min[now]=min(Min[now],Min[rson]); } int query(int l,int r,int now,int L,int R) { if(l>=L&&r<=R) return Min[now]; int re=inf,mid=(l+r)>>1; if(L<=mid) re=min(re, query(l,mid,lson,L,R)); if(R>mid) re=min(re, query(mid+1,r,rson,L,R)); return re; } int main() { // setIO("input"); int i,j,k=1,lk=0; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) { scanf("%d",&A[i]); A[i]^=A[i-1]; } for(i=1;i<=m;++i) { scanf("%d%d",&pp[i].l,&pp[i].r); pp[i].id=i; } build(1,n,1); sort(pp+1,pp+1+m,cmp); for(i=0;i<N;++i) lst[i]=-1; lst[0]=0; for(i=k=1;k<=m;++k) { for(;i<=pp[k].r&&i<=n;++i) { if(lst[A[i]]!=-1) { update(1,n,1,lst[A[i]]+1,i-lst[A[i]]); } lst[A[i]]=i; } int tmp=query(1,n,1,pp[k].l,pp[k].r); output[pp[k].id]=(tmp==inf)?-1:tmp; } for(i=1;i<=m;++i) printf("%d\n",output[i]); return 0; }