[洛谷P1168]中位数(Splay)/(主席树)
Description
给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[2], …, A[2k - 1]的中位数。即前1,3,5,……个数的中位数。
N ≤ 100000
Solution
这题方法很多,这里介绍splay的打法
求中位数即求第$(k+1)/$2小的数,用splay维护即可,只有2中操作:插入,旋转
在树上记录一个\(c(u)\)表示节点\(u\)的子树有几个节点,用来判断第n小
只要在插入和旋转的时候维护就行了
Code
#include <cstdio>
#include <algorithm>
#define lc(x) T[(x)][0]
#define N 100010
int n,tot,k[N],T[N][2],s[N],rt,fa[N];
void rotate(int p){
int q=fa[p],y=fa[q],x=(T[q][1]==p);
T[q][x]=T[p][x^1];fa[T[q][x]]=q;
T[p][x^1]=q;fa[q]=p;
fa[p]=y;
if(y){
if(T[y][0]==q) T[y][0]=p;
else if(T[y][1]==q) T[y][1]=p;
}
s[p]=s[q];
s[q]=s[T[q][0]]+s[T[q][1]]+1;//这里维护c(u)
}
void splay(int x){
for(int y;y=fa[x];rotate(x))
if(fa[y]) rotate((x==lc(y))==(y==lc(fa[y]))?y:x);
rt=x;
}
void Insert(int x,int v){
if(!rt){
rt=++tot;
s[rt]=1;
k[rt]=v;
return;
}
int y;
while(y){
y=T[x][k[x]<v];
if(!y){
y=++tot;
k[y]=v;
T[y][0]=T[y][1]=0;
fa[y]=x;
s[x]++;s[tot]++;//c(u)初始化
T[x][k[x]<v]=y;
break;
}
x=y;
}
splay(y);
}
int Find(int x){
int r=0;
for(int u=rt;;){
if(r+s[T[u][0]]+1==x) return k[u];
if(r+s[T[u][0]]+1<x) r+=s[T[u][0]]+1,u=T[u][1];
else u=T[u][0];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
int t;
scanf("%d",&t);
Insert(rt,t);
if(i&1) printf("%d\n",Find((i>>1)+1));
}
return 0;
}
[洛谷P1168]中位数(Splay)/(主席树)的更多相关文章
- 洛谷P1168 中位数——set/线段树
先上一波链接 https://www.luogu.com.cn/problem/P1168 这道题我们有两种写法 第一种呢是线段树,我们首先需要将原本的数据离散化,线段树维护的信息就是区间内有多少个数 ...
- 洛谷P2617 Dynamic Rankings (主席树)
洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...
- 洛谷P3567 KUR-Couriers [POI2014] 主席树/莫队
正解:主席树/莫队 解题报告: 传送门! 这题好像就是个主席树板子题的样子,,,? 毕竟,主席树的最基本的功能就是,维护一段区间内某个数字的个数 但是毕竟是刚get到主席树,然后之前做的一直是第k大, ...
- 洛谷P3567[POI2014]KUR-Couriers(主席树+二分)
题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半 题解: 最近比赛太多,都没时间切水题了,刚好日推了道主席树裸题,就写了一下 然后 WA80 WA80 WA0 WA90 WA80 ?? ...
- 洛谷 P1168 中位数
题目描述 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数.[color=red]即[/color] ...
- 洛谷——P1168 中位数
P1168 中位数 题目描述 给出一个长度为NN的非负整数序列$A_i$,对于所有1 ≤ k ≤ (N + 1),输出$A_1, A_3, …, A_{2k - 1}A1,A3,…,A2k−1 ...
- 洛谷P3567 [POI2014]KUR-Couriers 主席树
挺裸的,没啥可讲的. 不带修改的主席树裸题 Code: #include<cstdio> #include<algorithm> using namespace std; co ...
- 洛谷$P3302$ 森林 $[SDOI2013]$ 主席树
正解:主席树 解题报告: 传送门! 口胡一时爽代码火葬场 这题想法不难,,,但显然的是代码应该还挺难打的 但反正我也不放代码,就写下题解趴$QwQ$ 第一问就是个$Count\ on\ a\ tree ...
- 洛谷 P1168 中位数(优先队列)
题目链接 https://www.luogu.org/problemnew/show/P1168 解题思路 这个题就是求中位数,但是暴力会tle,所以我们用一种O(nlogn)的算法来实现. 这里用到 ...
随机推荐
- C 碎片一 计算机知识
一.计算机知识 1, 计算机组成及工作原理 计算机是硬件和软件的结合体.硬件由主机箱和外部设备组成,主机主要包括CPU.内存.主板.硬盘.光驱.各种扩展卡.连接线.电源等:外部设备包括鼠标.键盘等.软 ...
- Teradata 认证系列 - 2. Teradata数据库总览
Teradata (以下简称TD) 总览本课的学习目标 描述Teradata数据库产品的功能 知晓支持的操作系统 描述Teradata的并行架构 解释线性可扩展性 列出Teradata DBA永远不需 ...
- LeetCode Excel Sheet Column Number 表列数
题意:天啊!我竟然看不懂题意,还去翻别人的代码才懂!给定一个字符串,求该字符串二十六进制的总值. 思路:'A'~'Z'就是1到26,"AA"=26+1=27,"BA&qu ...
- linux 命令——42 kill (转)
Linux 中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令.通常,终止一个前台进程可以 使用Ctrl+C键,但是,对于一个后台进程 ...
- raspberrypi&linux
Raspberrypi&linux 2018-01-23 19:54:01 Let's go!
- 微信小程序(底部导航的实现)
详情请看官方文档介绍: https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html 在根目录配置文件app.json中配置底部导航: ...
- iphone 弹出键盘,文本框自动向上移动。
1.让类继承UITextViewDelegate UITextView *inputTextView;UIScrollView * _scrollView; 2.在init函数中先创建scrollVi ...
- flash + php对称密钥加密的交互
这几天研究了下php和flash中的对称密钥加密的交互问题,经过研究以后决定,在项目中使用aes加密.问题也就来了,在flash中的加密数据如何与php的amf进行数据交互,最终决定使用base64编 ...
- 查看电脑是否安装node.js
打开命令行
- Java异常处理的9个最佳实践
无论你是新手还是资深程序员,复习下异常处理的实践总是一件好事,因为这能确保你与你的团队在遇到问题时能够处理得了它. 在 Java 中处理异常并不是一件易事.新手觉得处理异常难以理解,甚至是资深开发者也 ...