1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include<iostream> #include<cstdio> using namespace std; const int N=500000+100; long long read() { long long x=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } struct SegmentTree { #define mid ((now_l+now_r)>>1) static const int M=25*N; int size[M],son[M][2],to; inline void update(int now) { size[now]=size[son[now][0]]+size[son[now][1]]; } void Add(int now,int pre,int x,int now_l,int now_r) { if(now_l==now_r) { size[now]=size[pre]+1; return; } if(x<=mid) { son[now][1]=son[pre][1]; Add(son[now][0]=++to,son[pre][0],x,now_l,mid); } else { son[now][0]=son[pre][0]; Add(son[now][1]=++to,son[pre][1],x,mid+1,now_r); } update(now); } int Query(int now,int pre,int x,int now_l,int now_r) { if(now_l==now_r) return now_l; if(size[son[now][0]]-size[son[pre][0]]>=x) return Query(son[now][0],son[pre][0],x,now_l,mid); else if(size[son[now][1]]-size[son[pre][1]]>=x) return Query(son[now][1],son[pre][1],x,mid+1,now_r); return 0; } #undef mid }sgt; int root[N],n,m; int main() { n=read(),m=read(); for(int i=1;i<=n;i++) { int tmp=read(); sgt.Add(root[i]=++sgt.to,root[i-1],tmp,1,n); }
for(int i=1;i<=m;i++) { int l=read(),r=read(),mid=(r-l+1)/2+1; printf("%d\n",sgt.Query(root[r],root[l-1],mid,1,n)); } return 0; }
|