hdu 4417(划分树+二分)
来源:互联网 发布:linux top 指定进程 编辑:程序博客网 时间:2024/05/18 06:41
求一个静态区间里,小于等于H的数有多少个。
二分第k小,用划分树找到第一个大于H的数,它是第K小,那么就有K-1个数小于H。
代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAX 101000#define MID(a,b) (a+((b-a)>>1))int n,m;int sorted[MAX];struct ptree{ int val[MAX]; int num[MAX];};ptree tree[20];void build_tree(int l,int r,int p){ int i,j; if(l==r) return ; int mid=MID(l,r); int lsame=mid-l+1,same=0,ln=l,rn=mid+1; for(i=l;i<=r;i++) if(tree[p].val[i]<sorted[mid]) lsame--; for(i=l;i<=r;i++) { if(i==l) tree[p].num[i]=0; else tree[p].num[i]=tree[p].num[i-1]; if(tree[p].val[i]<sorted[mid]) { tree[p].num[i]++; tree[p+1].val[ln++]=tree[p].val[i]; } else if(tree[p].val[i]>sorted[mid]) { tree[p+1].val[rn++]=tree[p].val[i]; } else { same++; if(lsame>=same) { tree[p].num[i]++; tree[p+1].val[ln++]=tree[p].val[i]; } else { tree[p+1].val[rn++]=tree[p].val[i]; } } } build_tree(l,mid,p+1); build_tree(mid+1,r,p+1);}int query(int l,int r,int left,int right,int k,int p){ if(left==right) return tree[p].val[left]; int mid=MID(left,right); int lx,ly,rx,ry; /* lx表示从lft到st-1这段区间内有多少个数进入左子树 ly表示从st到ed这段区间内有多少个数进入左子树 rx表示从lft到st-1这段区间内有多少个数进入右子树 ry表示从st到ed这段区间内有多少个数进入右子树 */ if(l==left) { lx=0;ly=tree[p].num[r]; } else{ lx=tree[p].num[l-1];ly=tree[p].num[r]-lx; } if(k<=ly) { l=left+lx; r=left+lx+ly-1; return query(l,r,left,mid,k,p+1); } else { rx=l-left-lx; ry=r-l+1-ly; l=mid+rx+1; r=mid+rx+ry; return query(l,r,mid+1,right,k-ly,p+1); }}int main(){ int i,j,k; int L,R,H; int T,casei=0; int num; scanf("%d",&T); while(T--) { casei++; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) {scanf("%d",&tree[0].val[i]);sorted[i]=tree[0].val[i];} sort(sorted+1,sorted+n+1); build_tree(1,n,0); printf("Case %d:\n",casei); for(i=1;i<=m;i++) { scanf("%d%d%d",&L,&R,&H); L++;R++; num=R-L+1; if(query(L,R,1,n,num,0)<=H) {printf("%d\n",num);continue;} if(query(L,R,1,n,1,0)>H) {printf("0\n");continue;} int Min=1,Max=num,mid,pos; while(Min<Max) { mid=(Min+Max)>>1; int temp=query(L,R,1,n,mid,0); if(temp<=H) {Min=mid+1;pos=Min;} else {Max=mid;pos=Max;} } printf("%d\n",pos-1); } } return 0;}
0 0
- hdu 4417(划分树+二分)
- HDU 4417 划分树+二分
- hdu 4417 划分树+二分
- HDU 4417 划分树+二分
- 【HDU】4417 Super Mario(划分树+二分)
- HDU 4417 Super Mario(划分树+二分)
- hdu 4417 Super Mario--二分--划分树
- HDU 4417 Super Mario(划分树+二分)
- HDU-4417-Super Mario(划分树+二分)
- 【划分树+二分】HDU 4417 Super Mario
- HDU 4417Super Mario 划分树 + 二分
- HDU 4417 Super Mario 划分树+二分
- HDU-4417 Super Mario,划分树+二分!
- HDU 3727 Jewel(划分树 + 二分)
- HDU 4417-Super Mario(划分树-二分查找)
- HDU 4417 Super Mario (树状数组+离线处理)(划分树+二分答案)
- hdu 4417(划分树)
- hdu4417(划分树)--二分
- linux:用systemtap来修改下linux内核变量的值
- ZOJ 1450 Minimal Circle 点集的最小圆覆盖
- Ubuntu下自动安装NodeJs的脚本
- 纯CSS3发光分享按钮
- UVa 11369 - Shopaholic
- hdu 4417(划分树+二分)
- 多线程之CS(关键段)
- vs2010导出dll的问题
- 静态内部类的使用
- 理论篇-地图学与GIS制图的基础理论(一)
- 美国千余商店收银系统遭攻击,致交易数据泄露。
- 20 个 SublimeText 插件
- 【Linux】Linux下tar指令
- 整理的一些常用的js表单验证