给出 n 个数,m个询问,对于 每个询问 输出[l,r]区间里面 小于等于 h 的数个数
排序离线处理
#include "iostream"
#include "algorithm"
using namespace std;
struct High
{
int h,id;
}high[100010];
struct Mark
{
int id,l,r,x;
}mark[100010];
struct comp
{
int l,r,sum;
}data[300010];
int ans[100010];
bool cmp1(const High a,const High b)
{
return a.h<b.h;
}
bool cmp2(const Mark a,const Mark b)
{
return a.x<b.x;
}
void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].sum=0;
if (l==r) return ;
mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
void insert(int n,int k)
{
int mid;
data[k].sum++;
if (data[k].l==data[k].r) return ;
mid=(data[k].l+data[k].r)/2;
if (n<=mid) insert(n,k*2);
else insert(n,k*2+1);
}
int search(int l,int r,int k)
{
int mid;
if (data[k].l==l && data[k].r==r)
return data[k].sum;
mid=(data[k].l+data[k].r)/2;
if (r<=mid) return search(l,r,k*2);
else
if (l>mid) return search(l,r,k*2+1);
else
return search(l,mid,k*2)+search(mid+1,r,k*2+1);
}
int main()
{
int Case,ii,n,m,j,i;
scanf("%d",&Case);
for (ii=1;ii<=Case;ii++)
{
scanf("%d%d",&n,&m);
for (i=0;i<n;i++)
{
scanf("%d",&high[i].h);
high[i].id=i;
}
for (i=0;i<m;i++)
{
scanf("%d%d%d",&mark[i].l,&mark[i].r,&mark[i].x);
mark[i].id=i;
}
sort(high,high+n,cmp1);
sort(mark,mark+m,cmp2);
memset(ans,0,sizeof(ans));
printf("Case %d:\n",ii);
j=0;
build(0,n-1,1);
for (i=0;i<m;i++)
{
while (j<n && high[j].h<=mark[i].x)
insert(high[j++].id,1);
ans[mark[i].id]=search(mark[i].l,mark[i].r,1);
}
for (i=0;i<m;i++)
printf("%d\n",ans[i]);
}
return 0;
}