poj-2104(主席树)
来源:互联网 发布:MySQL 设置多个主键 编辑:程序博客网 时间:2024/05/20 12:48
主席树,函数式线段树。
新建的线段树相对前面的改变较少,建树时便可充分利用与前面重叠部分的空间,在新加入节点时便只需开辟需要改变的树节点。
第i个线段树代表了原数列前i个数的存储,所以在求解原数列任意l~r区间的第k小值问题时,通过sum[r].l-sum[l].l的值与k比较即可知道该值在左或右区间,逐步缩小区间便可。
很好的数据结构。
题意:给一段序列和m个询问,问l~r区间的第k小数是多少。
//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<stdio.h>#include<math.h>#include <string>#include<string.h>#include<map>#include<queue>#include<set>#include<utility>#include<vector>#include<algorithm>#include<stdlib.h>using namespace std;#define eps 1e-8#define pii pair<int,int>#define inf 0x3f3f3f3f#define rd(x) scanf("%d",&x)#define rd2(x,y) scanf("%d%d",&x,&y)#define ll long long int#define mod 1000000007#define maxn 100005#define maxm 5000005int m,n,nn,tot;int a[maxn],f[maxn],T[maxn];int sum[maxm],l[maxm],r[maxm];int h(int x){//该值在离散化后线段树的位置 return lower_bound(f+1,f+1+nn,x)-f;}void update(int pr,int lx,int rx,int v){//插入,即新建第i个线段树 l[++tot]=l[pr];r[tot]=r[pr];sum[tot]=sum[pr]+1; if(lx==rx) return; int mid=(lx+rx)>>1; if(v<=mid) { l[tot]=tot+1; update(l[pr],lx,mid,v); } else { r[tot]=tot+1; update(r[pr],mid+1,rx,v); }}void build(int rt,int lx,int rx){//初始化空树 sum[rt]=0; if(lx==rx) return; l[rt]=++tot; int mid=(lx+rx)>>1; build(tot,lx,mid); r[rt]=++tot; build(tot,mid+1,rx);}int query(int L,int R,int k,int lx,int rx){ if(lx==rx) return f[lx]; int tmp=sum[l[R]]-sum[l[L]]; int mid=(lx+rx)>>1; if(k<=tmp) return query(l[L],l[R],k,lx,mid); else return query(r[L],r[R],k-tmp,mid+1,rx);}int main(){ rd2(n,m); for(int i=1;i<=n;i++) { rd(a[i]);f[i]=a[i]; } sort(f+1,f+1+n); nn=unique(f+1,f+1+n)-f-1;//离散化线段树,并去重 tot=0; T[0]=0; build(0,1,nn); for(int i=1;i<=n;i++){ T[i]=tot+1; //T[i]记录第i个线段树的根 update(T[i-1],1,nn,h(a[i])); } int L,R,k; for(int i=1;i<=m;i++){ scanf("%d%d%d",&L,&R,&k); printf("%d\n",query(T[L-1],T[R],k,1,nn)); } return 0;}
0 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 (主席树)
- IOS 学习 模型初始化的方法
- PHP和Nginx的通信方式
- I18N/L10N 是什么
- 基于Web和二维码的文件传输服务
- 之变量分离/引用(Scope in PHP)
- poj-2104(主席树)
- cJSON库使用教程
- 函数
- Java的垃圾回收机制
- C#读取Excel并转化成Xml
- 经典String str = new String("abc");内存分配问题
- C#创建一个Word并打开
- 正则表达式学习笔记
- c#读写系统事件日志