hdu4417(单纯裸划分树)
2015-08-03 12:54
211 查看
来源:http://acm.hdu.edu.cn/showproblem.php?pid=4417
题意:给一些数,数中有重复的。还有一些询问,问的是[L,R] 区间内有多少个数小于h,有多次询问。
一般的方法肯定很容易超时,那这题就想到了划分树,接触过划分树的同学可能都知道用划分树查询区间内排列第k的数,这里只需把查询换为数值为k。用一个num表示小于等于k的数的个数,当k大于等于中位数就递归到右子数,同时num加上该区间内在左子数的个数
题意:给一些数,数中有重复的。还有一些询问,问的是[L,R] 区间内有多少个数小于h,有多次询问。
一般的方法肯定很容易超时,那这题就想到了划分树,接触过划分树的同学可能都知道用划分树查询区间内排列第k的数,这里只需把查询换为数值为k。用一个num表示小于等于k的数的个数,当k大于等于中位数就递归到右子数,同时num加上该区间内在左子数的个数
#include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+20; int tree[20] ,sorted ; int toleft[20] ; void build(int l,int r,int deq) { if(l==r) return; int mid=(l+r)>>1; int same=mid-l+1; for(int i=l;i<=r;i++) if(tree[deq][i]<sorted[mid]) same--; int L=l,R=mid+1; for(int i=l;i<=r;i++) { if(i==l) toleft[deq][i]=0; else toleft[deq][i]=toleft[deq][i-1]; if(tree[deq][i]<sorted[mid]||(tree[deq][i]==sorted[mid]&&same>0)) { tree[deq+1][L++]=tree[deq][i]; toleft[deq][i]++; if(tree[deq][i]==sorted[mid]) same--; } else tree[deq+1][R++]=tree[deq][i]; } build(l,mid,deq+1); build(mid+1,r,deq+1); } int num; void query(int L,int R,int l,int r,int k,int deq) { if(l>r) return; if(l==r) { if(tree[deq][l]<=k) num++; return ; } int mid=(L+R)>>1; int to1,to2; if(l==L) to1=0; else to1=toleft[deq][l-1]; to2=toleft[deq][r]-to1; int mm=(l+r)>>1; if(sorted[mid]<=k)//进入右子树查询 { num+=to2; int lpos=l-1-L+1-to1,rpos=r-l+1-to2;//cout<<sorted[mid]<<" "<<num<<" "<<to2<<" "<<mid+1+lpos<<" "<<mid+1+lpos+rpos-1<<endl; query(mid+1,R,mid+1+lpos,mid+1+lpos+rpos-1,k,deq+1); } if(sorted[mid]>k) return query(L,mid,L+to1,L+to1+to2-1,k,deq+1); } int main() { int T,q,l,r; scanf("%d",&T); int p=1; while(T--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&tree[0][i]); sorted[i]=tree[0][i]; } sort(sorted+1,sorted+1+n); build(1,n,0); int a,b,k; printf("Case %d:\n",p++); for(int j=1;j<=m;j++) { num=0; scanf("%d%d%d",&a,&b,&k); query(1,n,a+1,b+1,k,0); printf("%d\n",num); } //printf("\n"); } }
相关文章推荐
- HDU 2435 There is a war(修改或添加一条边的最小割 )经典
- python实现备份目录的方法
- NOIP模拟21题解
- poj 2379 连续素数和 打表
- linux 图形界面
- HDOJ 1312 Red and Black(简单dfs)
- SQL Server2000打开1433端口
- Jenkins持续编译、运行自动化用例
- POJ 1006:Biorhythms 中国剩余定理
- umeng如何能够实现强制更新?
- 查看触发器内容
- POJ 1006:Biorhythms 中国剩余定理
- 使用容器与命令
- 操作系统中作业、程序、进程、线程及管程的定义与联系
- 理解python的slice
- 【JVM】模板解释器--字节码的resolve过程
- Android开发之定义内部类简单实现60s倒计时
- ucp2p 库:三、配置文件
- js绑定onblur事件
- html+css布局的三种方式