码迷,mamicode.com
首页 > 其他好文 > 详细

「CQOI2009」中位数

时间:2020-01-31 22:52:47      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:bool   大于   amp   表示   play   define   cpp   display   getch   

「CQOI2009」中位数

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

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

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

「CQOI2009」中位数

标签:bool   大于   amp   表示   play   define   cpp   display   getch   

原文地址:https://www.cnblogs.com/zsbzsb/p/12246862.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!