POJ 2104 (主席树)
来源:互联网 发布:疯狂java讲义最新版pdf 编辑:程序博客网 时间:2024/05/20 14:18
问你区间第k小的数是多少,主席树入门题。
本来昨天继续看字符串后缀数组的,看完线段树想想那就顺便看看主席树把,先是找可读性高的材料,找了半天没找到几个,有图解的也是寥寥无几,看了半天感觉太抽象了,本来想放弃了,睡完午觉还是想坚持读材料,最后终于看懂原理,又要找可读性高的代码,一来二去就花了一天,吐血!,然后今天去看奶奶,回来才把这题静态第K小A掉,按照自己理解写的,其实可以不用build,但为了完整性还是习惯建一下,反正时间够。至于动态套树状数组的只能下次再看了,还是得先搞完字符串的,要加快进度了。。
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn=1e5+10;vector<int>v;int a[maxn],root[maxn],cnt=1;struct node{ int l,r,sum;}tr[maxn*40];int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}int build(int l,int r){//这里的l,r,是左孩子和右孩子的编号。 int id=cnt++; tr[id].l,tr[id].r,tr[id].sum=0; if(l==r) return id; int mid= l+r>>1; tr[id].l =build(l,mid); tr[id].r =build(mid+1,r); return id;}int updata (int l,int r,int ls,int k){//每次更新只有头到叶子结点这一条链改变。 int id=cnt++; tr[id]= tr[ls]; //先让新节点等于历史版本节点。 tr[id].sum++; //改sum; int mid = l+r>>1; if (l == r) return id; if (k<=mid) tr[id].l = updata(l,mid,tr[ls].l,k); else tr[id].r = updata(mid+1,r,tr[ls].r,k); return id;}int query(int l,int r,int x,int y,int k){//[1,r]-[1,l-1]=[l,r]; 找的是两个线段树做差的那棵线段树 if(l==r) return l; int mid=l+r>>1; int sum=tr[tr[y].l].sum-tr[tr[x].l].sum; //算左边的数,左节点的最大排名 if(k<=sum) return query(l,mid,tr[x].l,tr[y].l,k); //小于sum,在左边. else return query(mid+1,r,tr[x].r,tr[y].r,k-sum);//在右边,继续查的时候就减掉对应排名。}int main(){ int n,m; scanf("%d%d",&n,&m); 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()); //去重 root[0]=build(1,n); for(int i=1;i<=n;i++) root[i]=updata(1,n,root[i-1],getid(a[i])); //getid取离散化后排名 for(int i=1;i<=m;i++) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%d\n",v[query(1,n,root[l-1],root[r],k)-1]);//减1因为离散化后下标从1开始,v中存储从0开始 }}
阅读全文
1 0
- poj-2104(主席树)
- poj 2104 (主席树)
- POJ 2104(主席树)
- poj 2104(主席树)
- POJ-2104(主席树)
- POJ 2104 (主席树)
- poj 2104 主席树
- POJ 2104 主席树
- poj 2104 主席树 板子
- poj 2104 主席树 详解
- POJ 2104 K-th Number (主席树 || 划分树)
- POJ 2104 K-th Number (划分树 / 主席树)
- POJ 2104 K-th Number(主席树)
- poj 2104 主席树(区间第k大)
- POJ 2104 K-th Number(主席树)
- [POJ 2104] K-th Number (主席树)
- POJ 2104:K-th Number(主席树)
- POJ 2104 K-th Number (主席树)
- IF ELSE语句(嵌套)
- Kafka内核总结
- HDU
- CSS学习笔记—选择器
- linux下网络编程
- POJ 2104 (主席树)
- ICPC2015(沈阳)HDU5521 建图技巧+最短路
- Python基础内容(数据类型,列表,元组等)
- Codeforces Gym 100753J Souvenirs
- Ubuntu终端彻底删除软件
- number (二分答案)
- bzoj2738矩阵乘法
- Python自动化运维笔记(五):使用filecmp模块实现文件以及文件目录差异对比
- easyui Panel的add,remove,select