hdu 4417 2012杭州网络赛
给出 n 个数,m个询问,对于 每个询问 输出[l,r]区间里面 大于 h 的数个数,由于n和m都很大,直接搞肯定不行,可以用线段树求解。
线段树 每个区间 保存 与该区间长度一样 对应 的 数据段,然后进行排序,查询的时候 如果该区间包含在 要询问的区间,那么直接二分查上界即可,否则继续向下询问。。
[cpp]
#include<iostream>
#include<algorithm>
using namespace std;
#define lson u<<1
#define rson u<<1|1
#define MAXN 100010
int dat[MAXN];
struct Node{
int lef,rig;
//int sum;
int *sub;
}T[MAXN<<2];
void Build(int u,int l,int r){
T[u].lef=l;
T[u].rig=r;
T[u].sub=new int[r-l+3];
int subc=0;
for(int i=l;i<=r;i++)T[u].sub[subc++]=dat[i];
sort(T[u].sub,T[u].sub+subc);
if(l==r)return;
int mid=(l+r)>>1;
Build(lson,l,mid);
Build(rson,mid+1,r);
}
void finalizer(int u,int l,int r){
delete[] T[u].sub;
if(l==r)return;
int mid=(l+r)>>1;
finalizer(lson,l,mid);
finalizer(rson,mid+1,r);
}
int Query(int u,int l,int r,int h){
if(l<=T[u].lef&&T[u].rig<=r){
int cnt=upper_bound(T[u].sub,T[u].sub+r-l+1,h)-T[u].sub;
return cnt;
}
else{
if(r<=T[lson].rig)return Query(lson,l,r,h);
if(l>=T[rson].lef)return Query(rson,l,r,h);
else return Query(lson,l,T[lson].rig,h)+Query(rson,T[rson].lef,r,h);
}
}
int main(){
int t,n,q;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d",dat+i);
printf("Case %d:\n",cas);
Build(1,1,n);
int lf,rg,hg;
while(q--){
scanf("%d%d%d",&lf,&rg,&hg);
printf("%d\n",Query(1,lf+1,rg+1,hg));
}
finalizer(1,1,n);
}
}
补充:软件开发 , C++ ,