给出 n ≤ 5 e 5 n\leq5e5 n≤5e5的序列,每次询问一个区间是否有超过一半的数,这里的一半是下取整。直接离散化建主席树,查询到区间的时候判断左子树个数是否大于一半的个数,如果是递归左子树,否则递归右子树。最后的时候在判断叶子结点个数就行。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=5e5+7;
int a[N],b[N];
int rt[N],ls[32*N],rs[32*N],cnt[32*N];
int tot=0;
void update(int &o,int pre,int l,int r,int v) {
o=++tot;
cnt[o]=cnt[pre]+1;
ls[o]=ls[pre];
rs[o]=rs[pre];
if(l==r) return;
int mid=(l+r)>>1;
if(v<=mid) update(ls[o],ls[pre],l,mid,v);
else update(rs[o],rs[pre],mid+1,r,v);
}
int query(int o,int pre,int l,int r,int num) {
if(l==r) {
if(cnt[o]-cnt[pre]>num) return b[l];
else return 0;
}
int sum=cnt[ls[o]]-cnt[ls[pre]];
int mid=(l+r)>>1;
if(sum>num) return query(ls[o],ls[pre],l,mid,num);
else return query(rs[o],rs[pre],mid+1,r,num);
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
int sz=unique(b+1,b+1+n)-(b+1);
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+1+sz,a[i])-b;
for(int i=1;i<=n;i++) {
update(rt[i],rt[i-1],1,sz,a[i]);
}
for(int i=1;i<=m;i++) {
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(rt[r],rt[l-1],1,sz,(r-l+1)/2));
}
return 0;
}