当前位置: 代码迷 >> 综合 >> poj 2761 Feed the dogs 划分树
  详细解决方案

poj 2761 Feed the dogs 划分树

热度:92   发布时间:2024-01-19 06:09:28.0

题意:

给长度为n的数组和m个区间,求这m个区间中第k小的数。

分析:

数组静态,区间和k动态,划分树的定义题,上模板。

代码:

//poj 2761
//sep9
#include <iostream>
#include <algorithm>
using namespace std;
#define MID(a,b) (a+((b-a)>>1))
const int maxN=100010;
struct Node
{int val[maxN],num[maxN];	
};struct Partition_tree
{int n,order[maxN];Node t[20];void init(int len){n=len;for(int i=1;i<=n;++i){scanf("%d",&order[i]);t[0].val[i]=order[i];}sort(order+1,order+1+n);build(1,n,0);	}		void build(int l,int r,int k){if(l==r) return;int mid=MID(l,r);		int lsame=mid-l+1,same=0,ln=l,rn=mid+1;for(int i=l;i<=r;++i)if(t[k].val[i]<order[mid]) --lsame;for(int i=l;i<=r;++i){if(i==l) t[k].num[i]=0;else t[k].num[i]+=t[k].num[i-1];		if(t[k].val[i]<order[mid])t[k].num[i]++,t[k+1].val[ln++]=t[k].val[i];else if(t[k].val[i]>order[mid])t[k+1].val[rn++]=t[k].val[i];else{same++;if(same<=lsame)t[k].num[i]++,t[k+1].val[ln++]=t[k].val[i];else t[k+1].val[rn++]=t[k].val[i];}}build(l,mid,k+1);build(mid+1,r,k+1);}int query(int st,int ed,int x,int l,int r,int k){if(l==r) return t[k].val[l];int lx,ly,rx,ry,mid=MID(l,r);if(st==l) lx=0,ly=t[k].num[ed];else lx=t[k].num[st-1],ly=t[k].num[ed]-t[k].num[st-1];if(ly>=x){st=l+lx;ed=l+lx+ly-1;return query(st,ed,x,l,mid,k+1);}else{rx=st-1-l+1-lx;ry=ed-st+1-ly;st=mid+1+rx;ed=mid+1+rx+ry-1;	return query(st,ed,x-ly,mid+1,r,k+1); }}
}tree;int main()
{int n,m;while(scanf("%d%d",&n,&m)==2){tree.init(n);while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);printf("%d\n",tree.query(a,b,c,1,n,0));}		}	return 0;	
} 


  相关解决方案