BZOJ1303: [CQOI2009]中位数图

题目链接
题意很直白了,在1~n的排列中寻找以b为中位数的序列个数。
首先可以记下b的位置,因为是‘1~n的排列’,所以每个数只出现一次;
而要求b是中位数,我们知道,在一个个数为奇数的数列中,成为中位数的条件就是比它大的数字个数=比他小的数字个数,我们又记下了b的位置,所以具体到左右,就是:
  b左边比他大的数字个数+b右边比他大的数字个数=b左边比他小的数字个数+b右边比它小的数字个数
即:左大+右大=左小+右小
    左大-左小=右小-右大=-(右大-右小)
明白了这点,我们可以维护一个类似于前缀和的数组来表示在b的左右比它大的数字个数
再根据乘法原理,就可以出解
【code】:
var
  i,j,k,b,x,y,point,n:longint;
  a:array[0..100100]of longint;
  left,right:array[-100100..100100]of longint;
  ans:longint;
begin
  readln(n,b);
  for i:=1 to n do begin
    read(a[i]);
    if a[i]=b then point:=i;
  end;
  x:=0;
  left[0]:=1;
  right[0]:=1;
  for i:=point-1 downto 1 do begin
    if a[i]>b then inc(x) else deC(x);
    inc(left[x]);
  end;
  x:=0;
  for i:=point+1 to n do begin
    if a[i]>b then inc(x) else dec(x);
    inc(right[x]);
  end;
  ans:=0;
  for i:=-n to n do
    ans:=ans+left[i]*right[-i];
  writeln(ans);
end.
posted @ 2015-07-25 10:35  Vincent_hwh  阅读(115)  评论(0编辑  收藏  举报