//一个考数据结构的题,我用线段树做的,先分层分区间排序,后面对目的区间的里的数二分找就是可以了,这个题型,在刘汝佳的题里面出现过,而且这里只需查找,不要更新,所以就更容易解了,这题解法有很多,划分树+二分,我想也能解吧;
//线段树+二分代码如下:
#include<stdio.h> #include<algorithm> using namespace std; struct node { int d[110000]; }td[22]; int find(int dep,int l,int r,int v) { int mid,start=l,end=r; if(td[dep].d[l]>v)return 0; else if(td[dep].d[r]<=v)return r-l+1; while(1) { mid=(start+end)>>1; if(start==mid)break; if(td[dep].d[mid]>v) { end=mid-1; if(td[dep].d[end]<=v) return end-l+1; } else start=mid; } if(td[dep].d[mid]>v)mid--; return mid-l+1; } void build(int dep,int l,int r) { int j,mid; for(j=l;j<=r;j++) td[dep].d[j]=td[dep-1].d[j]; if(l==r) return ; else { mid=(l+r)>>1; build(dep+1,l,mid); build(dep+1,mid+1,r); sort(td[dep].d+l,td[dep].d+r+1); } } int query(int dep,int l,int r,int a,int b,int v) { int mid; if(a==l&&b==r) return find(dep,l,r,v); else { mid=(l+r)>>1; if(b<=mid) return query(dep+1,l,mid,a,b,v); else if(b>mid&&a<=mid) return query(dep+1,l,mid,a,mid,v)+query(dep+1,mid+1,r,mid+1,b,v); else return query(dep+1,mid+1,r,a,b,v); } } int main() { int n,m,i,l,r,h,cass,cas; scanf("%d",&cass); for(cas=1;cas<=cass;cas++) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&td[0].d[i]); build(1,1,n); printf("Case %d:\n",cas); while(m--) { scanf("%d%d%d",&l,&r,&h); printf("%d\n",query(1,1,n,l+1,r+1,h)); } } return 0; }