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

    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


    数论的神题!!!
    蒟蒻解法:O(n^2)肯定炸...又要%题解...
    正解:
    找到b在数列中的位置st,比b大的赋值为-1,比b小的赋值为1;
    用前缀和分别维护一下st左边和右边,最后对应相乘再相加(乘法原理)
    这里还需要用到一个l数组和r数组
    l[i]保存st左边不同的前缀和个数、r[i]保存st右边不同的前缀和个数
    注意由于数组不能为负,所以整体右移。
    PS:因为自己一个也算,记得预处理

    详见代码:
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int f=1,x=0;char ch;
        while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return f*x;
    }
    int sum[210000],a[210000];
    int n,b,st;
    int l[210000],r[210000];
    int main()
    {
        n=read(),b=read();
        for(int i=1;i<=n;i++)
        {
            int x=read();
            if(x<b)a[i]=-1;
            else if(x==b)a[i]=0,st=i;
            else a[i]=1;
        }
        memset(sum,0,sizeof(sum));
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        l[n]=1;r[n]=1;
        for(int i=st-1;i>=1;i--)
            sum[i]=sum[i+1]+a[i],l[sum[i]+n]++;
        for(int i=st+1;i<=n;i++)
            sum[i]=sum[i-1]+a[i],r[sum[i]+n]++;
        int ans=0;
        for(int i=0;i<=2*n-1;i++)
            ans+=l[i]*r[2*n-i];
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Mybatis学习记录
    北京信息科技大学第十一届程序设计竞赛E-- kotori和素因子(深搜)
    eclipse快捷键记录
    牛客小白月赛15A 斑羚飞渡
    台州学院第十二届校赛记录(B,C,E,H,I,J,L)
    3.13 模拟赛
    bzoj 4827 礼物
    bzoj 3252 攻略
    bzoj 5457 城市
    bzoj 3681 Arietta
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/7860331.html
Copyright © 2011-2022 走看看