【bzoj1303】[CQOI2009]中位数图

一个大于b的数和一个小于b的数可以互相抵消,所以我们用1和-1表示。

从b向两边扩展,left[i]表示b左边抵消后有i个数比b小的可能数,right[i]表示b右边抵消后有i个数比b大的可能数。

ans=sigma(left[i]*right[i]).

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
  
#define N 200010
  
int n,b,k;
 
int ans; 
 
int a[N];
int l[N],r[N],sum[N];
  
int main()
{
    scanf("%d%d",&n,&b);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if (a[i]==b)
            k=i,a[i]=0;
        else
            a[i]=a[i]>b ? 1 : -1;
    }
    l[n]=1;
    r[n]=1;
    for (int i=k-1;i>=1;i--)
    {
        sum[i]=sum[i+1]+a[i];
        l[sum[i]+n]++;
    }
    for (int i=k+1;i<=n;i++)
    {
        sum[i]=sum[i-1]+a[i];
        r[sum[i]+n]++;
    }
    for (int i=1-n;i<=n-1;i++)
        ans+=l[i+n]*r[(n<<1)-(i+n)];
    printf("%d",ans);
    return 0;
}

  

posted @ 2016-07-23 19:46  Yangjiyuan  阅读(155)  评论(0编辑  收藏  举报