题意
给出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;
}