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.