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
  • 相关阅读:
    003 Leaflet 第三个demo 地图上的面积测量
    002 Leaflet 第二个demo 地图上的矩形拉框选择
    001 Leaflet 第一个demo 加载天地图
    This关键字,打印花瓣的数量
    Myeclipse8.5 添加Tomcat7
    WGS84经纬度 与 web 墨卡托相互转化 工具类
    java list集合去重复
    response 下载文件
    jquery实现可拖拽的div
    linux 前端环境搭建
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5351151.html
Copyright © 2011-2022 走看看