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

bzoj[CQOI2009]中位数图

时间:2018-03-01 13:35:31      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:int   左右   log   for   amp   class   ret   body   c++   

又是一道巧妙的题

将大于b的数标为1,将小于b的数标为-1

以b为界限,向两边分别求后缀和与前缀和,用l,r分别统计左右两边每个前缀和的数量

因为前缀和有负数所以整体加个n

于是答案就是l[i]*r[2*n-i]//和为2*n,即减去加上的n,和为0,此时b为中位数

 

因为题目中说要满足长度为奇数,此时若两个和加起来为2*n,个数相加一定为偶数,加上一个b就为奇数了

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int n,b,l[maxn<<1],pos;
int a[maxn],r[maxn<<1];

int main()
{
    scanf("%d%d",&n,&b);
    for(int i=1;i<=n;++i){
        
        scanf("%d",&a[i]);
        if(a[i]==b)pos=i,a[i]=0;
        if(a[i]>b)a[i]=1;
        else if(a[i]<b)a[i]=-1;
    }
    l[n]=r[n]=1;//b本身
        int ans=0,x=0;
    for(int i=pos-1;i>=1;--i){x+=a[i];l[x+n]++;}x=0;
    for(int i=pos+1;i<=n;++i){x+=a[i];r[x+n]++;}
    for(int i=0;i<=2*n;++i)ans+=l[i]*r[2*n-i];
    printf("%d\n",ans);
    return 0;
}

 

bzoj[CQOI2009]中位数图

标签:int   左右   log   for   amp   class   ret   body   c++   

原文地址:https://www.cnblogs.com/oi-forever/p/8487809.html

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