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

    想明白算法之后特别水,因为b只有可能出现一次,所以直接在b的左右找就行了,比他大的为1,比他小的为-1,然后维护前缀和就行了。

    假如b有可能出现多次呢?按照这种方法好像也很好办,就是枚举每个点就行了,复杂度有点大,所以直接求一遍前缀和就行了。

    题干:

    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

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int n,b,point;
    int a[100010],sum[200010];
    int l[100010],r[100010];
    int main()
    {
        read(n);read(b);
        duke(i,1,n)
        {
            read(a[i]);
            if(a[i] > b)
            a[i] = 1;
            else if(a[i] == b)
            {
                a[i] = 0;
                point = i;
            }
            else
            a[i] = -1;
        }
        l[n] = 1;r[n] = 1;
        lv(i,point - 1,1)
        {
            sum[i] = sum[i + 1] + a[i];
            l[sum[i] + n]++;
        }
        duke(i,point + 1,n)
        {
            sum[i] = sum[i - 1] + a[i];
            r[sum[i] + n] ++;
        }
        int ans = 0;
        duke(i,0,2 * n - 1)
        {
            ans += l[i] * r[2 * n - i]; 
        }
        printf("%d
    ",ans);
        return 0;
    }
    /*
    7 4
    5 7 2 4 3 1 6
    */
  • 相关阅读:
    HDUOJ---1863畅通工程
    HDUOJ---1879 继续畅通工程
    HDUOJ---1102Constructing Roads
    HDUOJ---1102Constructing Roads
    hdu--DFS
    poj1611---The Suspects
    nyoj-----幸运三角形
    HDUOJ --2523
    HDUOJ---1195Open the Lock
    HDUOJ----2952Counting Sheep
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9642491.html
Copyright © 2011-2022 走看看