zoukankan      html  css  js  c++  java
  • [BZOJ1303] [CQOI2009] 中位数图

    Description

      给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。

    Input

      第一行为两个正整数n和b ,第二行为1~n 的排列。

    Output

      输出一个整数,即中位数为b的连续子序列个数。

    Sample Input

    7 4
    5 7 2 4 3 1 6

    Sample Output

    4

    HINT

      第三个样例解释:{4}, {7,2,4}, {5,7,2,4,3}和{5,7,2,4,3,1,6}
      N<=100000

    Source

    Solution

      本题总时限1s,那么一个测试点0.1s,需要一个O(n)的算法,好像排序都不能用。

      我们换一种思路:

      设a[cur] = b, [l, r]表示满足题意的一个区间。

      因为b一定在序列中,所以l < cur,r > cur,因为b是中位数,所以比b大的数的个数=比b小的数的个数。

      令c[n] = a[n]~a[cur]中,大于b的数的个数减小于b的数的个数,或c[n] = a[cur]~a[n]中,小于b的数的个数减大于b的数的个数。

      所以若[l, r]满足条件,必有c[l] == c[r]。

      统计答案时用桶排序维护答案即可保证复杂度。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int a[100005], c[100005], sum[200005];
     4 int main()
     5 {
     6     int n, b, cur, ans = 0;
     7     cin >> n >> b;
     8     for(int i = 1; i <= n; i++)
     9     {
    10         cin >> a[i];
    11         if(b == a[i]) cur = i;
    12     }
    13     for(int i = cur; i; i--)
    14     {
    15         sum[c[i] + n]++;
    16         c[i - 1] = c[i] + (a[i - 1] > b ? 1 : -1);
    17     }
    18     for(int i = cur; i <= n; i++)
    19     {
    20         ans += sum[c[i] + n];
    21         c[i + 1] = c[i] + (a[i + 1] > b ? -1 : 1);
    22     }
    23     cout << ans << endl;
    24     return 0;
    25 }
    View Code
  • 相关阅读:
    PHP序列化和反序列化
    移动端纯css超出盒子出现横向滚动条
    css3盒子flex
    css怎么设置2个div同行,第一个固定宽度,第二个占满剩余的部分
    PHP对象基础
    常用header头
    【转载】文件上传那些事儿,文件ajax无刷上传
    简单工厂模式(Simple Factory Pattern)
    单例模式(singleton)
    UML类图
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5351151.html
Copyright © 2011-2022 走看看