[LUOGU] P3871 [TJOI2010]中位数
题目描述
给定一个由N个元素组成的整数序列,现在有两种操作:
1 add a
在该序列的最后添加一个整数a,组成长度为N + 1的整数序列
2 mid 输出当前序列的中位数
中位数是指将一个序列按照从小到大排序后处在中间位置的数。(若序列长度为偶数,则指处在中间位置的两个数中较小的那个)
例1:1 2 13 14 15 16 中位数为13
例2:1 3 5 7 10 11 17 中位数为7
例3:1 1 1 2 3 中位数为1
输入输出格式
输入格式:
第一行为初始序列长度N。第二行为N个整数,表示整数序列,数字之间用空格分隔。第三行为操作数M,即要进行M次操作。下面为M行,每行输入格式如题意所述。
输出格式:
对于每个mid操作输出中位数的值
输入输出样例
输入样例#1:
6
1 2 13 14 15 16
5
add 5
add 3
mid
add 20
mid
输出样例#1:
5
13
说明
对于30%的数据,1 ≤ N ≤ 10,000,0 ≤ M ≤ 1,000
对于100%的数据,1 ≤ N ≤ 100,000,0 ≤ M ≤ 10,000
序列中整数的绝对值不超过1,000,000,000,序列中的数可能有重复
每个测试点时限1秒
Splay,kth
#include<iostream>
#include<cstdio>
using namespace std;
inline int rd() {
int ret=0,f=1;
char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}
const int MAXN=1000005;
int num;
int val[MAXN],cnt[MAXN],siz[MAXN];
int ch[MAXN][2],fa[MAXN];
int root,tot;
inline int newnode(int x){num++;val[++tot]=x;cnt[tot]=siz[tot]=1;return tot;}
inline bool check(int x){return x==ch[fa[x]][1];}
inline void pushup(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];}
void rotate(int x){
int y=fa[x],z=fa[fa[x]];
bool ck=check(x);
fa[ch[x][ck^1]]=y;ch[y][ck]=ch[x][ck^1];
ch[x][ck^1]=y;fa[y]=x;fa[x]=z;
if(z) ch[z][ch[z][1]==y]=x;
pushup(y);pushup(x);
}
void splay(int x){
for(int f=fa[x];f;rotate(x),f=fa[x])
if(fa[f]) rotate(check(x)==check(f)?f:x);
root=x;
}
void insert(int x){
if(!root){root=newnode(x);return;}
int cur=root,f=0;
while(1){
if(val[cur]==x){num++;cnt[cur]++;pushup(cur);pushup(f);splay(cur);return;}
f=cur;cur=ch[cur][x>val[cur]];
if(!cur){cur=newnode(x);fa[cur]=f;ch[f][x>val[f]]=cur;pushup(f);splay(cur);return;}
}
}
int kth(int x){
int cur=root;
while(1){
if(x<=siz[ch[cur][0]]) cur=ch[cur][0];
else{
x-=siz[ch[cur][0]]+cnt[cur];
if(x<=0) return val[cur];
cur=ch[cur][1];
}
}
}
int n,m;
int main(){
n=rd();
for(int i=1;i<=n;i++) insert(rd());
m=rd();
char s[10];
for(int i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='a') insert(rd());
else printf("%d\n",kth((num+1)/2));
}
return 0;
}
[LUOGU] P3871 [TJOI2010]中位数的更多相关文章
- 【题解】Luogu P3871 [TJOI2010]中位数
平衡树板题 原题传送门 这道题要用Splay,我博客里有对Splay的详细介绍 每次加入一个数,把数插入平衡树中 并且要记录一共有多少个数 每次查询就查询平衡树中第(总数-1)/2+1个数 十分暴力 ...
- 洛谷 P3871 [TJOI2010]中位数 解题报告
P3871 [TJOI2010]中位数 题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前 ...
- 洛谷——P3871 [TJOI2010]中位数
P3871 [TJOI2010]中位数 一眼秒掉,这不是splay水题吗,套模板 #include<bits/stdc++.h> #define IL inline #define N 1 ...
- 洛谷P3871 [TJOI2010]中位数(splay)
题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将一个序列按照从 ...
- P3871 [TJOI2010]中位数
傻逼题 维护两个系统堆即可 #include<bits/stdc++.h> #define il inline #define vd void typedef long long ll; ...
- luoguP3871 [TJOI2010]中位数
题目链接 luoguP3871 [TJOI2010]中位数 题解 平衡树 代码 #include<vector> #include<cstdio> #include<cs ...
- 题解 P3871 【[TJOI2010]中位数】
orz各位大佬,题解太强了,主席树,堆,线段树,splay,还有暴力,太巨了.所以我用的是fhq treap(好像更高级).算了. 反正都是平衡树,这道题就是动态求中位数,不会做的同学可以先做弱化版P ...
- 洛谷 题解 P3871 【[TJOI2010]中位数】
这题先定义一个大根堆(maxn)维护mid(n为奇数mid+1)的元素.再定义一个小根堆(minn)维护mid(n为奇数mid+1)到n的元素.然后对于插入元素的情况进行分类讨论. 当add x时 一 ...
- TJOI2010中位数
中位数 上面是题目链接. 这一题比较水. 思路非常显然. 用mid查询时,只要返回中间值就行了. 主要就是add操作. 我们肯定不能插在末尾,然后用系统快排,这样只有30分. 那么正确的操作应该是二分 ...
随机推荐
- 基础BFS+DFS poj3083
//满基础的一道题 //最短路径肯定是BFS. //然后靠右,靠左,就DFS啦 //根据前一个状态推出下一个状态,举靠左的例子,如果一开始是上的话,那么他的接下来依次就是 左,上 , 右 , 下 // ...
- 用hdparm获取硬盘参数
hdparm是Linux下一款能够获取和设置SATA/IDE设备参数的工具. 1.获取硬盘参数 $ sudo hdparm -i /dev/sda$ sudo hdparam -i /dev/sda ...
- LuoguP2320/CF1037A 用二进制表示数的奥妙重重方法 By cellur925
题目描述 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政. 有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一件宝物引起了 ...
- C++类的默认函数
在C++中,一个类有八个默认函数: 默认构造函数: 默认拷贝构造函数: 默认析构函数: 默认重载赋值运算符函数: 默认重载取址运算符函数: 默认重载取址运算符const函数: 默认移动构造函数(C++ ...
- 「开源」目前见过的最好的开源OA产品
这是我目前见过的最好的开源OA产品.功能完整,代码结构清晰.值得推荐. 1.项目介绍 oasys是一个OA办公自动化系统,使用Maven进行项目管理,基于springboot框架开发的项目,mysql ...
- js实时获取并显示当前时间的方法
- 1-docker基础
docker有三个基本概念:镜像/容器/仓库 镜像:一个完整的root文件系统,但并非一个iso的打包文件,而是使用分层存储.构建镜像时,是一层一层的.新的镜像,也可以在原有镜像上添加新层. 容器:是 ...
- MessageDigest简介(与MD5加密有关)
参考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html 参考来源:http://blog.csdn.net/hudashi/article/ ...
- 关于MyBatis的两种写法
刚接触MyBatis是在Jike的视频中学习的,但是之后又发现和项目中的MyBatis的用法不太一致.上网找了好多资料,发现网上的教程分为两种写法: 第一种,是jike视频中的写法,写好map.xml ...
- 144 Binary Tree Preorder Traversal 二叉树的前序遍历
给定一棵二叉树,返回其节点值的前序遍历.例如:给定二叉树[1,null,2,3], 1 \ 2 / 3返回 [1,2,3].注意: 递归方法很简单,你可以使用迭代方法来解决 ...