CQOI2009中位数图

原来在vijos上做过,当时根本看不懂

现在看起来这么水……

x记录从b向左连续走比k大的有多少个

y记录从b向右连续走比k大的有多少个

最后根据乘法原理乘一下 

不过要加上x[0]+y[0]+1

因为实际上满足条件的序列有四种情况:

一、只选b,即为1

二、只在b左边选,即为x[0]

三、只在b右边选,即为y[0]

四、在两边都选,即为x[i]*y[-i]

Q.E.D

代码:

 1 var i,n,k,tmp:longint;
 2     sum,ans:int64;
 3     x,y:array[-100000..100000] of longint;
 4     a:array[0..100000] of longint;
 5 procedure init;
 6  begin
 7    readln(n,tmp);
 8    for i:=1 to n do
 9     begin
10       read(a[i]);
11       if a[i]=tmp then k:=i;
12     end;
13  end;
14 procedure main;
15  begin
16    fillchar(x,sizeof(x),0);
17    fillchar(y,sizeof(y),0);
18    for i:=k-1 downto 1 do
19      if a[i]>tmp then a[i]:=1 else a[i]:=-1;
20    sum:=0;
21    for i:=k-1 downto 1 do
22      begin
23      sum:=sum+a[i];
24      inc(x[sum]);
25      end;
26    for i:=k+1 to n do
27      if a[i]>tmp then a[i]:=1 else a[i]:=-1;
28    sum:=0;
29    for i:=k+1 to n do
30      begin
31      sum:=sum+a[i];
32      inc(y[sum]);
33      end;
34    ans:=0;
35    for i:=-n to n do inc(ans,x[i]*y[-i]);
36    inc(ans,x[0]);inc(ans,y[0]);
37    writeln(ans+1);
38  end;
39 begin
40   init;
41   main;
42 end.      
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/3801130.html