hdu 4417 划分树+二分
2014-08-06 15:43
387 查看
/*划分树+二分,二分第k个数 题意:给一列数..若干个询问..问(l,r,h)...在[l,r]范围内..有多少个数小于等于h*/ #include<stdio.h> #include<algorithm> #include<string.h> #define N 100100 using namespace std; int st ,val[20] ,num[20] ; void build(int x,int y,int cen) { if(x==y) return; int mid=(x+y)>>1,i,l=x,r=mid+1,same=mid-x+1; for(i=x;i<=y;i++) if(val[cen][i]<st[mid]) same--; for(i=x;i<=y;i++) { int flag=0; if(val[cen][i]<st[mid]||(val[cen][i]==st[mid]&&same)) { flag=1; val[cen+1][l++]=val[cen][i]; if(val[cen][i]==st[mid]) same--; } else { val[cen+1][r++]=val[cen][i]; } num[cen][i]=num[cen][i-1]+flag; } build(x,mid,cen+1); build(mid+1,y,cen+1); } int query(int st,int ed,int k,int x,int y,int cen) { if(x==y) return val[cen][x]; int mid=(x+y)>>1; int lx=num[cen][st-1]-num[cen][x-1]; int ly=num[cen][ed]-num[cen][st-1]; int rx=st-1-x+1-lx; int ry=ed-st+1-ly; if(k<=ly) return query(x+lx,x+lx+ly-1,k,x,mid,cen+1); else { st=mid+rx+1; ed=mid+rx+ry; return query(st,ed,k-ly,mid+1,y,cen+1); } } int main() { int t,n,m,i,j,k,l,r,ans,mid,a,cnt=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(num,0,sizeof(num)); for(i=1;i<=n;i++) { scanf("%d",&st[i]); val[0][i]=st[i]; } sort(st+1,st+1+n); build(1,n,0); printf("Case %d:\n",cnt++); while(m--) { scanf("%d%d%d",&i,&j,&k); i++; j++; l=1; r=j-i+1; ans=0; while(l<=r) { mid=(l+r)>>1; a=query(i,j,mid,1,n,0); if(a<=k) { l=mid+1; ans=mid; } else r=mid-1; } printf("%d\n",ans); } } return 0; }
相关文章推荐
- HDU-4417-Super Mario(划分树+二分)
- HDU 4417 Super Mario (划分树)(二分)
- HDU-4417 Super Mario,划分树+二分!
- HDU 4417 Super Mario (树状数组+离线处理)(划分树+二分答案)
- HDU 4417 划分树+二分
- hdu 4417(划分树+二分)
- HDU 4417 划分树+二分
- HDU 4417 Super Mario(划分树+二分)
- hdu 4417 Super Mario 划分树+二分
- 【HDU】4417 Super Mario(划分树+二分)
- HDU 4417 划分树+二分
- HDU 4417 - Super Mario (求区间小于h的数 划分树 二分 线段树 树状数组)
- HDU 4417 Super Mario(划分树+二分)
- HDU 4417 Super Mario(划分树+二分)
- hdu 4417 划分树
- HDU - 4417 Super Mario 主席树+二分
- hdu 4417 划分树
- hdu 4417 划分树加二分 求区间内小于num的数的个数
- HDU 4417 (二分 + 区间第k大)
- HDU 4417 Super Mario 划分树/树状数组