看完题目没用模板直接写了,写完用了15分钟。结果测试根本过不了,用了30分钟才排除错误。经验告诉我:对于问题应该先分析,再写代码。
思路:由于查询的h是所有在l-r位置区间内比自己小的数,对于一次查询:把所有比该查询h小的更新好,再查询即可。
所以可以把n个数按高度排序,m次查询也按高度排序。如果还有比此次查询的h更小的a[p].h,更新该a[p].id的个数。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N=100005;
struct node{
int l,r,h,id;
}q[N];
struct height{
int h,id;
}a[N],t;
int cmp(node a,node b){
return a.h<b.h;
}
int cmp1(height a,height b){
return a.h<b.h;
}
int ans[N],num[N*4];
void build(int l,int r,int rt){
num[rt]=0;
if(l==r)
return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void push_up(int rt){
num[rt]=num[rt*2]+num[rt*2+1];
}
void update(int p,int c,int l,int r,int rt){
if(l==r){
num[rt]++;
return;
}
int m=(l+r)>>1;
if(p<=m)
update(p,c,lson);
if(p>m)
update(p,c,rson);
push_up(rt);
}
int query(int a,int b,int l,int r,int rt){
if(a<=l&&b>=r)
return num[rt];
int m=(l+r)>>1,rst=0;
if(a<=m)
rst+=query(a,b,lson);
if(b>m)
rst+=query(a,b,rson);
return rst;
}
int main(){
int tt,n,m,cases=1;
for(cin>>tt;tt>0;tt--){
cin>>n>>m;
for(int i=0;i<n;i++){
scanf("%d",&a[i].h);
a[i].id=i;
}
build(0,n-1,1);
sort(a,a+n,cmp1);
a[n].h=1e9;
for(int i=0;i<m;i++)
scanf("%d %d %d",&q[i].l,&q[i].r,&q[i].h),q[i].id=i;
sort(q,q+m,cmp);//按高度排序
int cnt=0;
for(int i=0;i<m;i++){
while(a[cnt].h<=q[i].h){
update(a[cnt].id,1,0,n-1,1);
cnt++;
}
ans[q[i].id]=query(q[i].l,q[i].r,0,n-1,1);
}
printf("Case %d:\n",cases++);
for(int i=0;i<m;i++)
printf("%d\n",ans[i]);
}
return 0;
}