| 12
 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;
 }
 
 
 |