[BZOJ1303] [CQOI2009]中位数图

传送门

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( N2 )级别
其实,我们并不关心合法的位置,处理出两侧比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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值