给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。
显然出现次数超过一半的数最多只有1个
建出主席树,在树上二分查找即可
/**************************************************************
Problem: 3524
User: bdzxt
Language: C++
Result: Accepted
Time:4160 ms
Memory:124340 kb
****************************************************************/
#include<bits/stdc++.h>
#define LL long long
#define clr(x,i) memset(x,i,sizeof(x))
using namespace std;
const int N=500005;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct Node{
int l,r,sum;
}t[N*20];
int n,m,cnt,a[N],rk[N],sz;
int rt[N];
void upd(int l,int r,int &x,int y,int pos)
{
t[++cnt]=t[y];t[cnt].sum++;x=cnt;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)
upd(l,mid,t[x].l,t[y].l,pos);
else
upd(mid+1,r,t[x].r,t[y].r,pos);
}
int query(int l,int r,int x,int y,int K)
{
if(l==r)return l;
int mid=(l+r)>>1;
if(t[t[y].l].sum-t[t[x].l].sum>K)
return query(l,mid,t[x].l,t[y].l,K);
else if(t[t[y].r].sum-t[t[x].r].sum>K)
return query(mid+1,r,t[x].r,t[y].r,K);
else return 0;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=rk[i]=read();
sort(rk+1,rk+n+1);
sz=unique(rk+1,rk+n+1)-rk-1;
for(int i=1;i<=n;i++)
{
int v=lower_bound(rk+1,rk+sz+1,a[i])-rk;
upd(1,sz,rt[i],rt[i-1],v);
}
while(m--)
{
int x=read(),y=read();
int ret=query(1,sz,rt[x-1],rt[y],(y-x+1)/2);
if(!ret)printf("0\n");
else printf("%d\n",rk[ret]);
}
return 0;
}