划分树
来源:互联网 发布:海隆软件 编辑:程序博客网 时间:2024/05/02 00:40
虽然sunshine大神说划分树只是用来求第k小数这一个用处,但还是好好学习!!;
划分树建树的过程就是一个模拟快排的过程。
在建树的过程中,需要先取中间值,然后,小于中间值的放在左边,大于中间值的放在右边,在这个过程中,还需要记录第d层第i个树之前的左边的数。
poj 2104
下面写程序
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define maxn 101000using namespace std;struct node{ int s[maxn],c[maxn];};node t[50];int a[maxn];void build(int p,int l,int r){ if(l==r)return ; int mid=l+r>>1,x=l,y=mid+1; int nm=0,cnt=0; for(int i=mid;a[i]==a[mid];i--)nm++; for(int i=l;i<=r;i++) { if(t[p].s[i]<a[mid]) { t[p+1].s[x++]=t[p].s[i]; cnt++; t[p].c[i]=cnt; continue; } if(t[p].s[i]>a[mid]) { t[p+1].s[y++]=t[p].s[i]; t[p].c[i]=cnt; continue; } if(nm) { t[p+1].s[x++]=t[p].s[i]; cnt++; t[p].c[i]=cnt; nm--; } else { t[p+1].s[y++]=t[p].s[i]; t[p].c[i]=cnt; } } build(p+1,l,mid); build(p+1,mid+1,r);}int num(int l,int r,int k,int p,int b,int e){ if(l==r)return t[p].s[l]; int mid=b+e>>1,s,ss; if(l==b) {s=0;ss=t[p].c[r];} else{s=t[p].c[l-1];ss=t[p].c[r]-s;} if(k<=ss) { return num(b+s,b+s+ss-1,k,p+1,b,mid); } else { return num(mid+l-b-s+1,mid+r-ss-s-b+1,k-ss,p+1,mid+1,e); }}int main(){ int n,m; scanf("%d%d",&n,&m); int cnt=0; for(int i=1;i<=n;i++) { scanf("%d",&t[1].s[i]); a[++cnt]=t[1].s[i]; } sort(a+1,a+cnt+1); build(1,1,n); while(m--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); printf("%d\n",num(x,y,z,1,1,n)); } return 0;}
0 0
- 划分树
- 【划分树】
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- 划分树
- Nuclear Arms Race
- 数据结构实验之二叉树二:遍历二叉树
- TOJ 3982.Vacation
- JS中Attribute 和 property的区别
- JZOJ4683 矩阵
- 划分树
- 数据结构实验之二叉树的建立与遍历
- 3000门徒内部训练绝密视频(泄密版)第9课:彻底实战详解使用IntelliJ IDEA下的Spark程序开发
- ubuntu下搭建android开发环境(一)安装ubuntu系统(by 星空武哥)
- 我的开发之路-与你同行
- java中ArrayList 、LinkList的区别分析---程序中设比较时间
- struts2+spring+mybatis datagrid增删改查以及分页的实现
- 文件操作-按行加密解密
- appium 自动化测试之Android客户端