题意:超级玛丽的一款游戏。
知道了n 个连续位置处砖块的高度,有m个如下询问
l r h :区间[l,r] 中高度小于等于h的砖块有多少个。
分析:线段树。。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define clr(x)memset(x,0,sizeof(x))
#define maxn 100005
struct wall
{
int v,xu;
}w[maxn];
struct node
{
int l,r,h,xu,res;
}q[100005];
int cmp1(wall a,wall b)
{
return a.v<b.v;
}
int cmp2(node a,node b)
{
return a.h<b.h;
}
int cmp3(node a,node b)
{
return a.xu<b.xu;
}
int c[maxn];
int n;
int lowbit(int x)
{
return (x)&(-x);
}
void add(int pos)
{
while(pos<=n)
{
c[pos]+=1;
pos+=lowbit(pos);
}
}
int sum(int pos)
{
if(pos<0)
return 0;
int s=0;
while(pos>0)
{
s+=c[pos];
pos-=lowbit(pos);
}
return s;
}
int main()
{
int t,m,i,j,ca=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
clr(c);
for(i=1;i<=n;i++)
{
scanf("%d",&w[i].v);
w[i].xu=i;
}
sort(w+1,w+1+n,cmp1);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h);
q[i].l++; q[i].r++;
q[i].xu=i;
}
sort(q,q+m,cmp2);
j=1;
for(i=0;i<m;i++)
{
while(w[j].v<=q[i].h&&j<=n)
{
add(w[j].xu);
j++;
}
q[i].res=sum(q[i].r)-sum(q[i].l-1);
}
sort(q,q+m,cmp3);
printf("Case %d:\n",ca++);
for(i=0;i<m;i++)
printf("%d\n",q[i].res);
}
return 0;
}