既然看到了权值分块。。也就没什么好讲的了。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();}
return i*f;
}
inline void W(int x){
static int buf[50];
if(!x){putchar('0');return;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10;x/=10;}
while(buf[0])putchar(buf[buf[0]--]+'0');
}
const int Maxn=2e5+50;
int n,m,S_qry,S_val,lsh[Maxn<<2],tot,a[Maxn],bg[Maxn],ed[Maxn],ans[Maxn];
int cnt[Maxn<<2],bl_cnt[Maxn],bl[Maxn<<2];
struct Q{
int l,r,bl,id;
friend inline bool operator <(const Q &a,const Q &b){
return a.bl<b.bl||(a.bl==b.bl&&a.r<b.r);
}
}qry[Maxn];
inline void ins(int val){
((!cnt[val]++)?++bl_cnt[bl[val]]:0);
}
inline void del(int val){
((!--cnt[val])?--bl_cnt[bl[val]]:0);
}
inline int query(){
int nowpos=1;
while(bl_cnt[nowpos]==ed[nowpos]-bg[nowpos]+1)++nowpos;
nowpos=bg[nowpos];
while(cnt[nowpos])++nowpos;
return lsh[nowpos];
}
int main(){
n=read(),m=read();S_qry=sqrt(n)+1;
lsh[++tot]=0;
for(int i=1;i<=n;i++){
a[i]=read();
lsh[++tot]=a[i];
lsh[++tot]=a[i]+1;
}
sort(lsh+1,lsh+tot+1);
tot=unique(lsh+1,lsh+tot+1)-lsh-1;
S_val=sqrt(tot)+1;
for(int i=1;i<=n;i++)a[i]=lower_bound(lsh+1,lsh+tot+1,a[i])-lsh;
for(int i=1;;i++){
int lim=min(tot,i*S_val);
for(int j=(i-1)*S_val+1;j<=lim;j++)bl[j]=i;
bg[i]=(i-1)*S_val+1,ed[i]=lim;
if(lim==tot)break;
}
for(int i=1;i<=m;i++){
qry[i].l=read(),qry[i].r=read();qry[i].id=i;
qry[i].bl=(qry[i].l-1)/S_qry+1;
}
sort(qry+1,qry+m+1);
int L=1,R=0;
for(int i=1;i<=m;i++){
int l=qry[i].l,r=qry[i].r;
while(L<l)del(a[L++]);
while(L>l)ins(a[--L]);
while(R<r)ins(a[++R]);
while(R>r)del(a[R--]);
ans[qry[i].id]=query();
}
for(int i=1;i<=m;i++)W(ans[i]),putchar('\n');
}