Closest Equals
Closest Equals
https://ac.nowcoder.com/acm/problem/110867
分析
当我们看到区间的多次查询时,首先想到的可能就是离线了
我们尝试将查询的区间右端点排序
那么我们在向右移动指针时
如果前边出现了这个值
那么就可以将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; }