简单的主席树上二分。。。
出现次数超过区间长度一半的数肯定在左右子树中sz更大的那个中
向sz更大的子树上跳,如果节点总数就小于区间长度的一半则无解
因为没说ai取值范围所以离散化一下
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; int root[500500]; struct Node{ int lson,rson,sz; }Seg[500500*30]; int n,m,Nodecnt=0; void insert(int l,int r,int &o,int v){ int p=++Nodecnt; Seg[p]=Seg[o]; Seg[p].sz++; o=p; if(l==r) return; int mid=(l+r)>>1; if(v<=mid) insert(l,mid,Seg[o].lson,v); else insert(mid+1,r,Seg[o].rson,v); } int solve(int L,int R,int l,int r,int lo,int ro){ if(Seg[ro].sz-Seg[lo].sz<=((R-L+1)>>1)) return -1; if(l==r&&(Seg[ro].sz-Seg[lo].sz)>((R-L+1)>>1)) return l; int mid=(l+r)>>1; if(Seg[Seg[ro].rson].sz-Seg[Seg[lo].rson].sz>Seg[Seg[ro].lson].sz-Seg[Seg[lo].lson].sz) return solve(L,R,mid+1,r,Seg[lo].rson,Seg[ro].rson); else return solve(L,R,l,mid,Seg[lo].lson,Seg[ro].lson); } int a[500500],b[500500],len; int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+n+1); len=unique(b+1,b+n+1)-(b+1); for(int i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+len+1,a[i])-b; } for(int i=1;i<=n;i++){ root[i]=root[i-1]; insert(1,len,root[i],a[i]); } for(int i=1;i<=m;i++){ int l,r; scanf("%d %d",&l,&r); int rev=solve(l,r,1,len,root[l-1],root[r]); if(rev==-1){ printf("%d\n",0); } else{ printf("%d\n",b[rev]); } } return 0; }