分析
当我们看到区间的多次查询时,首先想到的可能就是离线了
我们尝试将查询的区间右端点排序
那么我们在向右移动指针时
如果前边出现了这个值
那么就可以将Pre[i]更改为i-Pre[i]
因为我们现在还没有扩展到右边的点
所以我们可以直接区间查询的最小值
线段树即可
因为我们需要将数值作为下标,所以需要离散化一次
当然,此题还有ST表+二分做的,可以参考这位巨佬或者这位巨佬
蒟蒻有一个神奇的思想--三维偏序,但感觉空间开不下。。。故咕
代码
//CF522D
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define LL long long
#define Lson (X<<1)
#define Rson (X<<1|1)
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(int i=A;i<=B;i++)
#define BOR(i,A,B) for(int i=A;i>=B;i--)
#define INF 0x3f3f3f3f
using namespace std;
const int MaxN=5e5+10;
int Num[MaxN],Last[MaxN],Cop[MaxN];
int Total,Test;
struct Node {
int Left,Right,ID;
friend bool operator < (Node A,Node B)
{ return ((A.Right<B.Right) || (A.Right==B.Right && A.Left<B.Left)); }
}Ask[MaxN];
int Tree[MaxN<<2],Ans[MaxN];
inline void File() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
inline void Push_up(int X) { Tree[X]=min(Tree[Lson],Tree[Rson]); }
inline void Update(int X,int L,int R,int Loc,int Temp) {
if(L==R) { Tree[X]=Temp; return; }
int Mid=(L+R)>>1;
if(Loc<=Mid) Update(Lson,L,Mid,Loc,Temp);
else Update(Rson,Mid+1,R,Loc,Temp);
Push_up(X);
}
inline int Get(int X,int L,int R,int From,int To) {
if(L>=From && R<=To) { return Tree[X]; }
int Mid=(L+R)>>1,Res=INF;
if(From<=Mid) Res=min(Res,Get(Lson,L,Mid,From,To));
if(To>Mid) Res=min(Res,Get(Rson,Mid+1,R,From,To));
return Res;
}
int main() {
// File();
scanf("%d %d",&Total,&Test);
FOR(i,1,Total) scanf("%d",&Num[i]),Cop[i]=Num[i];
sort(Cop+1,Cop+Total+1);
int Size=unique(Cop+1,Cop+Total+1)-(Cop+1);
FOR(i,1,Total) Num[i]=lower_bound(Cop+1,Cop+Size+1,Num[i])-Cop;
int Loc=1;
Cl(Tree,0x3f);
FOR(i,1,Test) scanf("%d %d",&Ask[i].Left,&Ask[i].Right),Ask[i].ID=i;
sort(Ask+1,Ask+Test+1);
FOR(i,1,Test) {
while(Loc<=Ask[i].Right) {
Cop[Loc]=Last[Num[Loc]];//废物利用
Last[Num[Loc]]=Loc;
if(Cop[Loc]!=0) Update(1,1,Total,Cop[Loc],(Loc-Cop[Loc]));
Loc++;
}
Ans[Ask[i].ID]=Get(1,1,Total,Ask[i].Left,Ask[i].Right);
}
FOR(i,1,Test) printf("%d\n",Ans[i]==INF ? -1 : Ans[i]);
// fclose(stdin);
// fclose(stdout);
system("pause");
return 0;
} 
京公网安备 11010502036488号