主席树-指针实现-找第k小数
主席树,其实就是N颗线段树
只是他们公用了一部分节点(๑•̀ㅂ•́)و✧
我大部分的代码是从一位大佬的那里看到的
我这个垃圾程序连Poj2104上的数据都过不了TLE
so希望神犇能给我看看,
顺便给和我一样的底层人物一点指针的帮助
也许是 new 太慢了
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100100
using namespace std;
struct XDS{
int l,r,dat;
XDS *lc,*rc;
XDS(){l=r=dat=0,lc=rc=NULL;}
};XDS *ro[N];
int n,qn,num[N],val[N],len;
void prerun(){//这是离散化的预处理
sort(val+0,val+n);
len=unique(val+0,val+n)-val;
}
int fvind(int x){//离散化get
return lower_bound(val+0,val+len,x)-val+1;
}
void Empty_total(XDS *&rt,int l,int r){//以l为左,r为右处理一颗空树,初始化
rt=new XDS();
rt->l=l;
rt->r=r;
if(l==r)return ;
int mid=(l+r)/2;
Empty_total(rt->lc,l,mid);
Empty_total(rt->rc,mid+1,r);
}
void dfs(XDS *rt){//调试用的,不用管
if(rt==NULL)return;
cout<<rt<<" "<<rt->l<<" "<<rt->r<<" "<<rt->dat<<"\n";
dfs(rt->lc);
dfs(rt->rc);
}
void add(XDS *his,XDS *&nrt,int v){//his:从上一个转移过来,nrt :现在在搞的 (同位转移)增加一个|V:离散化后
if(his==NULL)return ;//结束
if(nrt==NULL)nrt=new XDS();//新开节点
int l=his->l;nrt->l=l;
int r=his->r;nrt->r=r;
if(l==r){
nrt->dat=his->dat+1;
return ;
}
int mid=(l+r)/2;
if(v<=mid){//值在左侧
nrt->rc=his->rc;//直接拿右侧
add(his->lc,nrt->lc,v);//查左
}
else{//值在右侧
nrt->lc=his->lc;//直接拿左侧
add(his->rc,nrt->rc,v);//查右
}
nrt->dat=nrt->lc->dat+nrt->rc->dat;
}
int query(XDS *lrt,XDS *rrt,int k){//在lrt与rrt之间查第K大
int l=1,r=len;//二分查找
while(l<r){
int mid=(l+r)/2;
int cnt=rrt->lc->dat-lrt->lc->dat;/*两个树的左子树差
即在这个区间内在[0,mid]范围内的增加值 */
if(cnt>=k){//比k个多,往左搜
r=mid;
lrt=lrt->lc;
rrt=rrt->lc;//同步浏览
}
else {//比k个少,往右
l=mid+1;
k-=cnt;
lrt=lrt->rc;
rrt=rrt->rc;
}
}
return l;
}
int main(){
scanf("%d%d",&n,&qn);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
val[i-1]=num[i];
}
prerun();
Empty_total(ro[0],1,len);
// dfs(ro[0]);
for(int i=1;i<=n;i++){
add(ro[i-1],ro[i],fvind(num[i]));
}
int a,b,c;
for(int i=1;i<=qn;i++){
scanf("%d%d%d",&a,&b,&c);
// cout<<query(ro[a-1],ro[b],c)<<endl;
printf("%d\n",val[query(ro[a-1],ro[b],c)-1]);
}
return 0;
}
主席树-指针实现-找第k小数的更多相关文章
- 算法打基础——顺序统计(找第k小数)
这次主要是讲如何在线性时间下找n个元素的未排序序列中第k小的数.当然如果\(k=1 or k=n\),即找最大最小 数,线性时间内遍历即可完成,当拓展到一般,如中位数时,相关算法就值得研究了.这里还要 ...
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解
题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...
- 【树状数组套主席树】带修改区间K大数
P2617 Dynamic Rankings 题目描述给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+ ...
- HDU 2665(主席树,无修改第k小)
Kth number Time Limit: 15000/5000 MS (Java/Others) ...
- 可持久化线段树(主席树)——静态区间第k大
主席树基本操作:静态区间第k大 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=2e5+, ...
- 主席树 - 查询某区间第 K 大
You are working for Macrohard company in data structures department. After failing your previous tas ...
- 主席树铺垫——总区间第k小
题目描述(口糊) 先给定一个长度为n的数列,然后给m次操作,每次输入b,求第b小的数. 样例输入 5 7 4 10 9 23 5 1 2 3 4 5 样例输出 4 7 9 10 23 数据范围及温馨提 ...
- 主席树——求静态区间第k大
例题:poj2104 http://poj.org/problem?id=2104 讲解:http://blog.sina.com.cn/s/blog_6022c4720102w03t.html ht ...
随机推荐
- 007--linux常用命令nginx和nfs服务
作业: 集群搭建 1.部署nginx反向代理三个web服务,调度算法使用加权轮询: 2.所有web服务使用共享存储nfs,保证所有web都对其有读写权限,保证数据一致性: 一.nginx服务 1. 先 ...
- 洛谷 - P1142 - 轰炸 - 计算几何
https://www.luogu.org/problemnew/show/P1142 枚举一个基点,枚举另一个点找出斜率,约分后存入.记得要加上那个点本身. __gcd(x,y),返回值符号与y的符 ...
- Codeforces627A【数学·有意思】
题意: 求有多少对( a , b ),a+b=s,a^b=x.(正整数) 思路: a+b=a^b+a&b*2; #include <iostream> #include <c ...
- POJ3186【区间DP】
题意: 每次只能取两端,然后第 i 次取要val[ i ]*i,求一个最大值 一切都是错觉[读者省略此段] 这道题目一开始想的就是记忆化搜索,然后太天真了?好像是,一开始用一维dp[ i ]直接代表一 ...
- hdoj2859【DP基础】
/* 看题解A的. 总结:小矩阵--> 大矩阵 dp[i][j]=min(t,dp[i-1][j+1]+1); */ #include <iostream> #include < ...
- weui button的使用
1.迷你按钮的使用 <a href="javascript:;" class="weui-btn weui-btn_primary weui-btn_mini&qu ...
- bug日志-天坑,Spring Security的登陆报错:An internal error occurred while trying to authenticate the user.
在学习Spring Security的时候,我的编辑器给我报错:An internal error occurred while trying to authenticate the user. 明明 ...
- “XXX.Index”不扩展类“System.Web.UI.Page”,因此此处不允许的问题
“XXX.Index”不扩展类“System.Web.UI.Page”,因此此处不允许的问题 原因:设计页面继承的路径和后台.cs页面类的路径不一致造成的 看下图 这个是设计页面的样式 这个是后台cs ...
- 香港药品 ref
--公牛牌风湿骨刺丹30粒 参考网站--http://item.jd.com/1955815605.html?gjz=0#comments-list 88 --参考网站1,没有 http://www. ...
- C8051特点
C8051与传统51的区别在于优先权交叉开关.系统时钟.SFR寄存器几个方面: 一 优先权交叉开关:传统的51外设功能是固定分配或者复用分配到指定引脚,而C8051则是通过优先权交叉开关设置,即要想分 ...