POJ 2104 K-th Number 主席树(求区间第k大)
来源:互联网 发布:大数据未来发展 编辑:程序博客网 时间:2024/05/29 05:55
点击打开链接
主席书资料
题意:给出n个数,m次询问,[x,y]内第k小的数时多少?n<=1e5,m<=5000
主席树:对原序列的每个前缀i都建立一个线段树 维护值域[l,r]中的每个数,在前缀i的出现次数.
此时l,r不在表示为下标,l,r为第l~r小的数
先将原序列离散化后,更新出主席树
求[x,y]内第k大的数?
若第1~mid大的数在[x,y]中出现的次数sum>=k,则[x,y]的第k大就在左子树中,否则[x,y]第k大为右子树的第k-sum个
由于主席树保存了第l~r大的数在任意前缀y和x-1的的出现次数,则第l~mid大的数在区间[x,y]的出现次数为T[T[y].l].sum-T[T[x-1].l].sum
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N=2e5+20;int n,m,a[N],x,y,k;int root[N],cnt;struct node{int l,r,sum; //此时l,r不在表示下标,sum表示第l~r大的数的出现次数}T[N*40];vector<int> v;int getid(int x)//离散化 {return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}int build(int l,int r){int rt=++cnt;T[rt].sum=0;T[rt].l=T[rt].r=0;if(l==r) return rt;int mid=(l+r)>>1;T[rt].l=build(l,mid);//l保存左子树结点号T[rt].r=build(mid+1,r); return rt;}void update(int l,int r,int &x,int y,int k)//根据第i个数是第几大来更新 {T[++cnt]=T[y],T[cnt].sum++,x=cnt;if(l==r) return;int mid=(l+r)>>1;if(mid>=k) update(l,mid,T[x].l,T[y].l,k);elseupdate(mid+1,r,T[x].r,T[y].r,k);} int query(int l,int r,int x,int y,int k){if(l==r) return l; int mid=(l+r)>>1;int sum=T[T[y].l].sum-T[T[x].l].sum;if(sum>=k)return query(l,mid,T[x].l,T[y].l,k);elsereturn query(mid+1,r,T[x].r,T[y].r,k-sum); }int main(){while(cin>>n>>m){cnt=0;build(1,n);v.clear();for(int i=1;i<=n;i++)scanf("%d",&a[i]),v.push_back(a[i]);sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end()); for(int i=1;i<=n;i++)//前缀1~i和1~i-1只有一条链不同,那么root[i]其它结点只要用前一棵树的结点即可 update(1,n,root[i],root[i-1],getid(a[i]));// for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&k);int ans=query(1,n,root[x-1],root[y],k);printf("%d\n",v[ans-1]);//输出第k大离散化前的值 }}return 0;}
0 0
- POJ 2104 K-th Number 主席树(求区间第k大)
- 【主席树 求区间第k大】poj 2104 K-th Number
- poj 2107 K-th Number(主席树求区间第K大)
- POJ 2104(K-th Number-区间第k大-主席树)
- POJ 2104(K-th Number-区间第k大-主席树)
- POJ 2104 K-th Number 主席树 静态区间第K大
- 【POJ 2104】(K-th Number-区间第k大-主席树)
- POJ 2104 K-th Number (主席树 静态区间第K大)
- poj 2104 K-th Number (静态区间第k大,主席树)
- [poj 2104 K-th Number] 主席树 区间第K大
- POJ 2104 K-th Number 静态区间第k大 主席树
- POJ-2104 K-th Number (主席树 不带修改区间第k大)
- 用线段树求区间第K大(POJ 2104 K-th Number)
- POJ 2104 & HDU 2665 & POJ 2761 K-th Number (主席树入门题 区间第K大)
- POJ 2104K-th Number&&HDU 2665Kth number划分树 求区间第k大 裸题
- poj2104 K-th Number(静态区间k大,主席树)
- POJ2104-K-th Number-区间第k大-可持久化线段树/主席树
- POJ 2104-K-th Number(划分树)求区间内第k小的数
- hdu1087 Super Jumping! Jumping! Jumping!_LIS
- 【Linux】Ubuntu系统中Code::Blocks IDE安装全过程
- ubuntu下建立PPTP-VPN客户端拨号连接
- Maven入门6-配置tomcat
- 2017.3.25NOI模拟赛总结
- POJ 2104 K-th Number 主席树(求区间第k大)
- QT之GUI学习笔记(二十)---反走样
- 在centos阿里云服务器上配置apache+php+mysql环境
- Gson使用指南(二)
- windows7环境下github搭建过程(1)
- 算法小结——KM算法
- 2017网易实习前端面试题讨论
- fcgi4j与PHP-FPM通信遇到的问题
- 基本元器件之美标螺丝UNEF螺纹