「CQOI2009」中位数

Posted zsbzsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「CQOI2009」中位数相关的知识,希望对你有一定的参考价值。

「CQOI2009」中位数

传送门
这道题将会用到一点桶的思想。
首先我们可以在排列中先找到 (b) 的位置(找不到的话就直接输出 (0))。
然后我们从 (b) 的位置(设为 (p))开始拓展,容易发现有三种情况:

  • (b) 在子段左边界
  • (b) 在子段右边界
  • (b) 在子段中间位置

我们很容易想到,对于 (b) 在子段边界的情况可以直接扫描,记录一下小于 (b) 的数和大于 (b) 的数的个数即可。
对于 (b) 在序列中间的情况可以这样做:
类比我们处理其他两种情况的方法,我们都是记录了小于 (b) 和大于 (b) 的数的个数(简记为 (small)(big)
(small=big) 时,意味着当前 (b) 就是中位数,我们就可以将答案加一。
同样的对于这种情况,我们不难得到下面这个式子:
[small_{ ext{左}}+small_{ ext{右}}=big_{ ext{左}}+big_{ ext{右}}]
接下来移项:
[small_{ ext{左}}-big_{ ext{左}}=big_{ ext{右}}-small_{ ext{右}}]
那么我们就可以用桶来维护,具体方法如下:
在对一种边界情况进行处理时(以向右拓展为例),我们开一个桶 (tong[i]) 表示有多少种 (big-small) 等于 (i)。(为了防止数组越界可以同时加上一个数)
然后在对另一边进行处理时干一件这样的事: (ans ext{+=} tong[small - big])
这样我们就完成了的三种情况的方案数统计,可以见代码。
参考代码:

/*--------------------------------
  Code name: A.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <cstdio>
#define rg register
#define file(x)                                     freopen(x".in", "r", stdin);                    freopen(x".out", "w", stdout);
const int $ = 100010;
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
int a[$], tong[$ * 5], OFF = $ * 2;
int main() {
//  file("A");
    int n = read(), k = read(), p = 0;
    for (rg int i = 1; i <= n; ++i)
    { a[i] = read(); if (a[i] == k) p = i; }
    if (p == 0) return puts("0"), 0;
    int ans = 1, s1 = 0, b1 = 0, s2 = 0, b2 = 0;
    for (rg int i = p + 1; i <= n; ++i) {
        if (a[i] > k) ++b2; else ++s2;
        ++tong[b2 - s2 + OFF];
        if (s2 == b2) ++ans;
    }
    for (rg int i = p - 1; i >= 1; --i) {
        if (a[i] > k) ++b1; else ++s1;
        ans += tong[s1 - b1 + OFF];
        if (s1 == b1) ++ans;
    }
    printf("%d
", ans);
    return 0;
}

以上是关于「CQOI2009」中位数的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1303: [CQOI2009]中位数图

BZOJ 1303: [CQOI2009]中位数图

[CQOI2009]中位数图

「CQOI2009」中位数

[CQOI2009] 中位数 (前缀和)

BZOJ 1303: [CQOI2009]中位数图前缀和