例题:
题目描述:
在一个长度为 n n n 的无序数列 a a a 中,做 m m m 次操作,操作种类如下:
操作1:查询当前数列的中位数,用 C
表示
操作2:在数列的第
x
x
x 个数与第
y
y
y 个数中插入一个数
k
k
k ,用 T x y k
表示
操作3:删除数列中的第
x
x
x 个数 ,用 S x
表示
输入:
第一行,两个数
n
,
m
n,m
n,m
第二行,共
n
n
n 个数,即数列
a
a
a
接下来m行,每行都有一个操作
输出:
输出每次查询的结果
样例输入:
4 2
1 4 3 2
S 2
C
样例输出:
3
正如上题,在每次查询时都用普通方法求出中位数就可以,但如果查询次数太多,容易超时,所以需要一种快速维护中位数的方法。
方法介绍:
加入有一个无序数列:
1 | 6 | 3 | 5 | 2 | 4 | 7 |
---|
先对序列进行排序
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|
定义两个变量 l , r l,r l,r,如果数列中的数有奇数个,则用普通方法使 l , r l,r l,r 都指向中位数,如果数列中的数有偶数个,则使 l l l 指向中位数左边的第一个数, r r r指向中位数右边的第一个数,效果如图:
偶数:
1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|
l l l | r r r |
奇数:
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
l , r l,r l,r |
寻找规律:
我们以奇数为例,假如这时删除了数字 2 ,数列就变成了这样:
1 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|
l , r l,r l,r |
可以看到这时的中位数已经改变了,再按上述普通方法求出 l , r l,r l,r 的位置,我们需要把 r r r 右移一位,就是这样:
1 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|
l l l | r r r |
这样中位数就维护好了
然后我们再删除数字 7
这时就变成了这样:
1 | 3 | 4 | 5 | 6 |
---|---|---|---|---|
l l l | r r r |
显然我们又要重新按普通方法维护中位数,就需要把 r r r 左移一位
1 | 3 | 4 | 5 | 6 |
---|---|---|---|---|
l , r l,r l,r |
这下我们就能看到规律了:
如果删除的数在中位数左边,且删除后数列为奇数列,就把 l l l 右移一位,反之删除后数列为偶数列,就把 r r r 右移一位,
如果删除的数在中位数右边,且删除后数列为奇数列,就把 r r r 左移一位,反之删除后数列为偶数列,就把 l l l 左移一位。
重复上述模拟操作,也可以找到添加数的移动规律,这样就可以快速的在变化的数列中维护好中位数了。
还有有疑问可以在此处寻找更多优秀文章或者在评论中提出哦~