题目描述

给定一个由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: 复制

  1. 6
  2. 1 2 13 14 15 16
  3. 5
  4. add 5
  5. add 3
  6. mid
  7. add 20
  8. mid
输出样例#1: 复制

  1. 5
  2. 13

说明

对于30%的数据,1 ≤ N ≤ 10,000,0 ≤ M ≤ 1,000

对于100%的数据,1 ≤ N ≤ 100,000,0 ≤ M ≤ 10,000

序列中整数的绝对值不超过1,000,000,000,序列中的数可能有重复

每个测试点时限1秒

这题不是随便做么。。

口胡一下我能想到的做法吧,,

1.$M < 10000$的话vector暴力插入不知道能不能A,

2.直接用平衡树,我写的是splay,不想写代码的话可以用pb_ds里维护了siz域的红黑树

3.先离线,对权值离散化,然后用权值线段树查。

4.沿用https://www.luogu.org/problemnew/show/P1801这道题的做法

  1. #include<cstdio>
  2. using namespace std;
  3. const int MAXN = 1e6 + ;
  4. #define ls(x) ch[x][0]
  5. #define rs(x) ch[x][1]
  6. #define root ch[0][1]
  7. int fa[MAXN], val[MAXN], rev[MAXN], siz[MAXN], ch[MAXN][], tot = ;
  8. bool ident(int x) {
  9. return ch[fa[x]][] == x ? : ;
  10. }
  11. void connect(int x, int _fa, int opt) {
  12. fa[x] = _fa, ch[fa[x]][opt] = x;
  13. }
  14. void update(int x) {
  15. siz[x] = siz[ls(x)] + siz[rs(x)] + rev[x];
  16. }
  17. void rotate(int x) {
  18. int Y = fa[x], R = fa[Y];
  19. int Yson = ident(x), Rson = ident(Y);
  20. int B = ch[x][Yson ^ ];
  21. connect(B, Y, Yson);
  22. connect(x, R, Rson);
  23. connect(Y, x, Yson ^ );
  24. //tag
  25. update(Y); update(x);
  26. }
  27. void splay(int x, int to) {
  28. to = fa[to];
  29. while(fa[x] != to) {
  30. int y = fa[x];
  31. if(fa[y] == to) rotate(x);
  32. else if(ident(x) == ident(y)) rotate(y), rotate(x);
  33. else rotate(x), rotate(x);
  34. }
  35. }
  36. int NewNode(int _fa, int _val) {
  37. val[++tot] = _val;
  38. fa[tot] = _fa;
  39. siz[tot] = rev[tot] = ;
  40. return tot;
  41. }
  42. void insert(int x) {
  43. if(!root) {root = NewNode(, x); return ;}
  44. int now = root;
  45. while(now) {
  46. siz[now]++;
  47. if(val[now] == x) {rev[now]++; return ;}
  48. int nxt = val[now] < x;
  49. if(!ch[now][nxt]) {ch[now][nxt] = NewNode(now, x); splay(ch[now][nxt], root); return ;}
  50. now = ch[now][nxt];
  51. }
  52. }
  53. int ARank(int x) {
  54. int now = root;
  55. while(now) {
  56. //if(siz[now] == x) return val[now];
  57. int used = siz[now] - siz[rs(now)];
  58. if(x > siz[ls(now)] && x <= used) return val[now];
  59. if(used < x) x = x - used, now = ch[now][];
  60. else now = ch[now][];
  61. }
  62. }
  63. char opt[];
  64. int main() {
  65. #ifdef WIN32
  66. freopen("a.in", "r", stdin);
  67. #endif
  68. int N;
  69. scanf("%d", &N);
  70. for(int i = ; i <= N; i++) {
  71. int x; scanf("%d", &x);
  72. insert(x);
  73. }
  74. int Q;
  75. scanf("%d", &Q);
  76. while(Q--) {
  77. scanf("%s", opt + );
  78. if(opt[] == 'a') {
  79. int x;
  80. scanf("%d", &x);
  81. insert(x); N++;
  82. }
  83. else
  84. printf("%d\n", ARank(N / + (N & )));
  85. }
  86. return ;
  87. }

洛谷P3871 [TJOI2010]中位数(splay)的更多相关文章

  1. 洛谷——P3871 [TJOI2010]中位数

    P3871 [TJOI2010]中位数 一眼秒掉,这不是splay水题吗,套模板 #include<bits/stdc++.h> #define IL inline #define N 1 ...

  2. 洛谷 P3871 [TJOI2010]中位数 解题报告

    P3871 [TJOI2010]中位数 题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前 ...

  3. 洛谷 3871 [TJOI2010]中位数

    [题解] 平衡树模板题,不过因为可以离线,所以有别的做法.把询问倒着做,变成删掉数字.求中位数,于是可以二分+树状数组. #include<cstdio> #include<cstr ...

  4. 洛谷3871 [TJOI2010]中位数 维护队列的中位数

    题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将一个序列按照从 ...

  5. BZOJ3224/洛谷P3391 - 普通平衡树(Splay)

    BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...

  6. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  7. 洛谷 P3871 中位数

    ->题目链接 题解: 暴力 经鉴定,此题数据水到没朋友. #include<algorithm> #include<iostream> #include<cstdi ...

  8. [LUOGU] P3871 [TJOI2010]中位数

    题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将一个序列按照从 ...

  9. 洛谷 P1627 [CQOI2009]中位数 解题报告

    P1627 [CQOI2009]中位数 题目描述 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 输入输出格式 输入格式 ...

随机推荐

  1. 机器学习kNN

    from numpy import * import operator def createDataSet(): group = array([[1.0, 1.1], [1.0, 1.0], [0, ...

  2. 数组和矩阵(1)——Find the Duplicate Number

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  3. PAT 1040 Longest Symmetric String

    #include <cstdio> #include <cstdlib> using namespace std; ]; ]; int syslen(char str[], i ...

  4. 从零开始的全栈工程师——html篇1

    全栈工程师也可以叫web 前端 H5主要是网站 app 小程序 公众号这一块 HTML篇 html(超文本标记语言,标记通用标记语言下的一个应用.) “超文本”就是指页面内可以包含图片.链接,甚至音乐 ...

  5. html-其他常见标签的使用

    b:加粗 s:删除线 u:下划线 i:斜体 per:原样输出 sup:上标 sub:下标 p:段落标签 比br多一行 (CSS) div:自动换行 span:在一行显示 完整代码: <html& ...

  6. AMP+EPP3.0的开发环境配置

    经过摸索,总结出下列Apache.MySQL.PHP.EPP.ZendDebugger的开发环境配置方法: 版本: Apache: Apache-httpd-2.2.25-win32-x86-no_s ...

  7. Oracle 修改任何用户的密码

    1.通过sys用户以sysdba身份登陆: 2.修改用户密码:  alter user 用户名 identified by 密码; 比如修改system的密码为 manager : alter use ...

  8. 猿创|有赞的zan framework安装与使用[2]

    下载并安装comoser curl -sS https://getcomposer.org/installer | php 结果各种超时 不能忍,打开迅雷下载installer:https://get ...

  9. SpringMvc-自定义视图

    1.创建视图: 注意:创建视图的时候需要实现View接口的俩个方法 package com.atguigu.springmvc.views; import java.util.Date; import ...

  10. RAC修改spfile位置

    RAC修改spfile位置    [root@rac1 ~]# su - oracle  [oracle@rac1 ~]$ sqlplus  / as sysdba  SQL*Plus: Releas ...