hdu 2665 Kth number || poj 2761 Feed the dogs || poj 2104 K-th Number
来源:互联网 发布:js面向对象实现过程 编辑:程序博客网 时间:2024/05/16 00:37
都是划分树加线段树。
划分树定义为,它的每一个节点保存区间[lft,rht]所有元素,元素顺序与原数组(输入)相同,但是,两个子树的元素为该节点所有元素排序后(rht-lft+1)/2个进入左子树,其余的到右子树,同时维护一个num域,num[i]表示lft->i这个点有多少个进入了左子树。
这个输入的数据不可以重复。。
三个代码基本一样,就只有输入不同,第二个和第三个一样:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 100010int sorted[N];int anode[40][N];int line[40][N];void bulid(int l,int r,int n){ if(l==r) return; int mid=(l+r)>>1; int s=mid-l+1; for(int i=l;i<=r;i++) if(anode[n][i]<sorted[mid]) s--; int left=l; int right=mid+1; for(int i=l;i<=r;i++){ if(anode[n][i]<sorted[mid]) anode[n+1][left++]=anode[n][i]; else if(anode[n][i]==sorted[mid]&&s>0){ anode[n+1][left++]=anode[n][i]; s--; } else anode[n+1][right++]=anode[n][i]; line[n][i]=line[n][l-1]+left-l; } bulid(l,mid,n+1); bulid(mid+1,r,n+1); }int query(int L,int R,int l,int r,int n,int k){ if(l==r) return anode[n][l]; int mid=(L+R)>>1; int num=line[n][r]-line[n][l-1]; if(num>=k){ int nn=L+line[n][l-1]-line[n][L-1]; int mm=nn+num-1; return query(L,mid,nn,mm,n+1,k); } else{ int nn=r+line[n][R]-line[n][r]; int mm=nn-(r-l-num); return query(mid+1,R,mm,nn,n+1,k-num); } } int main(){ int t,i,n,m,a,b,c; scanf("%d",&t); while(t--){ scanf("%d %d",&n,&m); memset(anode,0,sizeof(anode)); for(i=1;i<=n;i++){ scanf("%d",&anode[0][i]); sorted[i]=anode[0][i]; } sort(sorted+1,sorted+1+n); bulid(1,n,0); for(i=0;i<m;i++){ scanf("%d %d %d",&a,&b,&c); printf("%d\n",query(1,n,a,b,0,c)); } } return 0; }
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 100010int sorted[N];int anode[40][N];int line[40][N];void bulid(int l,int r,int n){ if(l==r) return; int mid=(l+r)>>1; int s=mid-l+1; for(int i=l;i<=r;i++) if(anode[n][i]<sorted[mid]) s--; int left=l; int right=mid+1; for(int i=l;i<=r;i++){ if(anode[n][i]<sorted[mid]) anode[n+1][left++]=anode[n][i]; else if(anode[n][i]==sorted[mid]&&s>0){ anode[n+1][left++]=anode[n][i]; s--; } else anode[n+1][right++]=anode[n][i]; line[n][i]=line[n][l-1]+left-l; } bulid(l,mid,n+1); bulid(mid+1,r,n+1); }int query(int L,int R,int l,int r,int n,int k){ if(l==r) return anode[n][l]; int mid=(L+R)>>1; int num=line[n][r]-line[n][l-1]; if(num>=k){ int nn=L+line[n][l-1]-line[n][L-1]; int mm=nn+num-1; return query(L,mid,nn,mm,n+1,k); } else{ int nn=r+line[n][R]-line[n][r]; int mm=nn-(r-l-num); return query(mid+1,R,mm,nn,n+1,k-num); } } int main(){ int t,i,n,m,a,b,c; //scanf("%d",&t); while(~scanf("%d %d",&n,&m)){ // scanf("%d %d",&n,&m); memset(anode,0,sizeof(anode)); for(i=1;i<=n;i++){ scanf("%d",&anode[0][i]); sorted[i]=anode[0][i]; } sort(sorted+1,sorted+1+n); bulid(1,n,0); for(i=0;i<m;i++){ scanf("%d %d %d",&a,&b,&c); printf("%d\n",query(1,n,a,b,0,c)); } } return 0; }
- hdu 2665 Kth number || poj 2761 Feed the dogs || poj 2104 K-th Number
- 【主席树】poj2104 K-th Number && poj2761 Feed the dogs
- [POJ2104] K-th Number/[POJ2761] Feed the dogs
- POJ 2104K-th Number&&HDU 2665Kth number划分树 求区间第k大 裸题
- POJ-2761-Feed the dogs
- POJ 2761 Feed the dogs
- POJ 2761 Feed the dogs
- POJ 2761 Feed the dogs
- poj 2761 Feed the dogs
- poj 2761 Feed the dogs
- POJ 2104 & HDU 2665 K-th Number (划分树)
- POJ 2104 | HDU 2665 - K-th Number (划分树)
- 【划分树】 POJ 2104 HDU 2665 K-th Number 裸题
- poj 2104 K-th Number
- poj 2104 K-th Number
- Poj 2104 K-th Number
- POJ-2104-K-th Number
- POJ 2104 K-th Number
- 每日一题(61) - 找出左边比它小,右边比它大的数
- Ajax使用POST方式异步提交数据
- 从键盘输入11个数存入一维数组中,将该数组中左半部分与右半部分的值平移交换后重新存入该数组 中并输出?
- Android面试题精选,自己收藏下
- Android---App Widget(四)
- hdu 2665 Kth number || poj 2761 Feed the dogs || poj 2104 K-th Number
- 输入一行字符,统计单词个数?(单词:单个字母以上字母的集合)
- Linux下的图形界面——X Window的安装
- PHP Liunx 服务安全防范方案
- javascript面向对象的5种写法
- Hdu 4391 Paint The Wall
- 一行字符,单词个数的统计
- OC将对象赋给对象,及对象用对象初始化的内存地址变化
- ThinkPad指纹验证在win7无法使用的解决方法