D. Closest Equals(线段树)

题目链接:

D. Closest Equals

time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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|.

Input

The first line of the input contains a pair of integers nm (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.

Output

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.

Examples
input
5 3
1 1 2 3 2
1 5
2 4
3 5
output
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;
}

  

 
posted @ 2017-05-15 22:48  LittlePointer  阅读(343)  评论(0编辑  收藏  举报