中位数(median)
【题目描述】
给出1~n (n<=100000) 的一个序列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排序后,位于中间的数,例如序列4、5、 1、6、 3排序后为1、3、4、5、6,这个序列中间的的数是4,所以4就是这个序列的中位数。
【输入格式】
第一行为两个正整数n和b,第二行为1~n的序列
【输出格式】
输出一个整数,即中位数为b的连续子序列的个数
【输入样例1】
5 4
1 2 3 4 5
【输出样例1】
2
【输入样例2】
6 3
1 2 4 5 6 3
【输出样例2】
1
【输入样例3】
7 4
5 7 2 4 3 1 6
【输出样例3】
4
第三个样例解释:{4},{7,、2、4},{5、7、2、4、3},{5、7、2、4、3、1、6}。
==============================
朴素50分(O(N^3))
70分(O(N^2))记录两个数组,分别表示有多少个小于a[k]和大于a[k]
再枚举区间..
100分做法,明确中位数性质
==================
var
n,b:longint;
a:array[1..100000]of longint;
pre,next:array[-100000..100000]of longint;
procedure init;
begin
assign(input,'median.in');
assign(output,'median.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure main;
var
k:longint;
i:longint;
sum:longint;
ans:longint;
begin
readln(n,b);
for i:=1 to n do begin read(a[i]); if a[i]=b then k:=i; end;
fillchar(pre,sizeof(pre),0);
fillchar(next,sizeof(next),0);
sum:=0;
pre[0]:=1; next[0]:=1;
for i:=k-1 downto 1 do
begin
if a[i]<a[k] then inc(sum)
else dec(sum);
inc(pre[sum]);
end;
sum:=0;
for i:=k+1 to n do
begin
if a[i]>a[k] then inc(sum)
else dec(sum);
inc(next[sum]);
end;
ans:=0;
for i:=-n to n do inc(ans,pre[i]*next[i]);
writeln(ans);
end;
begin
init;
main;
terminate;
end.