D. Closest Equals(线段树)
题目链接:
You are given sequence a1, a2, ..., an and m queries lj, rj (1 ≤ lj ≤ rj ≤ n). For each query you need to print the minimum distance between such pair of elements ax and ay (x ≠ y), that:
- both indexes of the elements lie within range [lj, rj], that is, lj ≤ x, y ≤ rj;
- the values of the elements are equal, that is ax = ay.
The text above understands distance as |x - y|.
The first line of the input contains a pair of integers n, m (1 ≤ n, m ≤ 5·105) — the length of the sequence and the number of queries, correspondingly.
The second line contains the sequence of integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109).
Next m lines contain the queries, one per line. Each query is given by a pair of numbers lj, rj (1 ≤ lj ≤ rj ≤ n) — the indexes of the query range limits.
Print m integers — the answers to each query. If there is no valid match for some query, please print -1 as an answer to this query.
5 3
1 1 2 3 2
1 5
2 4
3 5
1
-1
2
题意:给一个区间,问这个区间里面相同的两个数的最小距离是多少;
思路:由于询问特别多,可以对右端点进行排序,然后按右端点从小到大更新与这个点相同的前一个位置的距离,然后线段树求[l,r]的最小值;
AC代码:
#include <bits/stdc++.h> using namespace std; const int maxn=5e5+10; const int inf=1e9; int n,m,ans[maxn],p[maxn]; map<int,int>mp; struct node { int l,r,id; }po[maxn]; int cmp(node x,node y){return x.r<y.r;} struct Tree { int l,r,mn; }tr[4*maxn]; void build(int o,int L,int R) { tr[o].l=L;tr[o].r=R;tr[o].mn=inf; if(L>=R)return ; int mid=(tr[o].l+tr[o].r)>>1; build(2*o,L,mid);build(2*o+1,mid+1,R); } void update(int o,int pos,int num) { if(tr[o].l==tr[o].r&&tr[o].l==pos){tr[o].mn=min(tr[o].mn,num);return ;} int mid=(tr[o].l+tr[o].r)>>1; if(pos<=mid)update(2*o,pos,num); else update(2*o+1,pos,num); tr[o].mn=min(tr[2*o].mn,tr[2*o+1].mn); } int query(int o,int L,int R) { if(L<=tr[o].l&&R>=tr[o].r)return tr[o].mn; int mid=(tr[o].l+tr[o].r)>>1; int tep=inf; if(L<=mid)tep=min(tep,query(2*o,L,R)); if(R>mid)tep=min(tep,query(2*o+1,L,R)); return tep; } int main() { scanf("%d%d",&n,&m); build(1,1,n); int x; for(int i=1;i<=n;i++) { scanf("%d",&x); if(mp[x])p[i]=mp[x],mp[x]=i; else mp[x]=i,p[i]=0; } for(int i=1;i<=m;i++)scanf("%d%d",&po[i].l,&po[i].r),po[i].id=i; sort(po+1,po+m+1,cmp); int r=1; for(int i=1;i<=m;i++) { while(r<=po[i].r) { if(p[r])update(1,p[r],r-p[r]); r++; } int tep=query(1,po[i].l,r-1); if(tep>=inf)ans[po[i].id]=-1; else ans[po[i].id]=tep; } for(int i=1;i<=m;i++)printf("%d\n",ans[i]); return 0; }