对于询问[i,j]
在[1..n]中我们看看小于mid的数字有多少个,显然如果个数的两倍<=j-i+1那么[1..mid]中就不存在这样的数,
反之检测大于mid有多少个
当然 如果两个都不行,就返回0
是可以递归的
#include<bits/stdc++.h>
#define N 500005
using namespace std;
int n,m,a[N],rt[N*100],lson[N*100],rson[N*100],tot,sum[N*100];
void build(int &now,int l,int r)
{
now=++tot;
if(l==r) return;
int mid=(l+r)>>1;
build(lson[now],l,mid);
build(rson[now],mid+1,r);
}
int update(int now,int l,int r,int x)
{
int newnode=++tot;
lson[newnode]=lson[now]; rson[newnode]=rson[now]; sum[newnode]=sum[now]+1;
if(l==r) return newnode;
int mid=(l+r)>>1;
if(x<=mid) lson[newnode]=update(lson[newnode],l,mid,x);
else rson[newnode]=update(rson[newnode],mid+1,r,x);
//pushup(now);
return newnode;
}
inline int query(int x,int y,int l,int r,int range)
{
if(l==r) return l;
int mid=(l+r)>>1;
if(2*(sum[lson[y]]-sum[lson[x]])>range) return query(lson[x],lson[y],l,mid,range);
if(2*(sum[rson[y]]-sum[rson[x]])>range) return query(rson[x],rson[y],mid+1,r,range);
else return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
cin>>n>>m;
build(rt[0],1,n);
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
rt[i]=update(rt[i-1],1,n,a[i]);
}
for(int i=1;i<=m;i++)
{
int l,r;
cin>>l>>r;
cout<<query(rt[l-1],rt[r],1,n,r-l+1)<<'\n';
}
return 0;
}
本文介绍了一种基于线段树的数据结构实现,用于解决区间查询问题,具体为在一个有序数组上进行范围查询,找出满足特定条件的元素。通过递归构建线段树并更新节点状态,可以高效地处理区间内的元素计数,进而解决复杂查询任务。
&spm=1001.2101.3001.5002&articleId=83869661&d=1&t=3&u=a5c327a7e8a94a53b67a61c8c344f24f)
217

被折叠的 条评论
为什么被折叠?



