您的位置:首页 > 其它

[BZOJ1303] [CQOI2009]中位数图

2015-09-25 18:50 288 查看

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1303

题目大意

给定1-n的全排列,询问连续奇数个数的中位数为m的组数

题解

由于是奇数个,那么除去m以外还有偶数个,由于m是中位数,所以偶数个数里大于m和小于m的数的个数相同

对于m我们要包含他,从他的左右两边来看

我们可以用O(N)的时间来求一个从第i位到m的那位比m大和比m小的数的个数

我们可以枚举m两侧[i,j]区间,然后用O(1)时间去判断合法,复杂度是O(N2N^2)级别

其实,我们并不关心合法的位置,处理出两侧比m大和比m小的数的差

我们发现:m左侧比m大的个数+m右侧比m大的个数=m左侧比m小的个数+m右侧比m小的个数时为合法情况

所以m左侧比m大的个数-m左侧比m小的个数=-(m右侧比m大的个数-m右侧比m小的个数)

根据组合的知识,把下标互为相反数的值乘起来就是ans了,0的时候要加1

var
x:array[0..100000]of longint;
z,y:array[0..100000,1..2]of longint;
t:array[-100000..100000,1..2]of int64;
i,j,k:longint;
n,m,tt:longint;
ans:int64;
begin
readln(n,m);
for i:=1 to n do
begin read(x[i]); if x[i]=m then tt:=i; end;
fillchar(t,sizeof(t),0);
y[tt,1]:=0; y[tt,2]:=0;
for i:=tt-1 downto 1 do
if x[i]<m
then begin y[i,1]:=y[i+1,1]+1; y[i,2]:=y[i+1,2]; inc(t[y[i,1]-y[i,2],1]); end
else begin y[i,1]:=y[i+1,1]; y[i,2]:=y[i+1,2]+1; inc(t[y[i,1]-y[i,2],1]); end;
for i:=tt+1 to n do
if x[i]<m
then begin y[i,1]:=y[i-1,1]+1; y[i,2]:=y[i-1,2]; inc(t[y[i,1]-y[i,2],2]); end
else begin y[i,1]:=y[i-1,1]; y[i,2]:=y[i-1,2]+1; inc(t[y[i,1]-y[i,2],2]); end;
ans:=0;
for i:=-100000 to 100000 do
if i<>0
then inc(ans,t[i,1]*t[-i,2])
else inc(ans,(t[i,1]+1)*(t[-i,2]+1));
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: