HDU 4417 离线线段树

来源:互联网 发布:医疗器械工程师 知乎 编辑:程序博客网 时间:2024/04/28 14:41

给出 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;}




0 0