【Bzoj1303】中位数图

12 篇文章 0 订阅

题意

给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。


解析

因为数都是不重复的,所以可以把左边小于它的记为+1,大于的记为-1,统计前缀和f。同理,右边大于的记为1,小于的记为-1,统计前缀和g,那么,如果左边某个数出现某次数的方法种数等于右边的,就根据乘法原理统计答案,特别地,f[0]=g[0]=1。数组下标要做一点处理。


#include <cstdio>
#include <algorithm>

#define Rep( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i<=(i##_END);i++)
#define For( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i++)
#define Lop( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i>=(i##_END);i--)
#define Dnt( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i--)

using std :: max;
using std :: min;

const int maxx = (100000<<1) + 25;
const int N = 100005;

int n,m,x,y,z;
int a[maxx],f[maxx],g[maxx];
int ans,tmp,pos;

int main(){
    scanf("%d%d",&n,&m);
    Rep( i , 1 , n ) scanf("%d",&a[i]);
    Rep( i , 1 , n ) if(a[i] == m) pos = i;
    f[N] = g[N] = 1;
    Dnt( i , pos-1 , 0 ) tmp += (a[i]<m)? 1 : -1,f[tmp+N] ++;
    tmp = 0;
    Rep( i , pos+1 , n ) tmp += (a[i]>m)? 1 : -1,g[tmp+N] ++;
    Rep( i , N-n , N+n ) ans += f[i]*g[i];
    printf("%d",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值