一个朴素的想法是把大于bb的数规约成11,小于bb的数规约成1-1,那么中位数为bb就是区间的所有1,1,01,-1,0的和为00

而给出的数列是一个排列,那么bb只有唯一的位置,从这个位置向两边求和,就可以找出题目要求的区间。

于是整个区间的和就变成了suml+0+sumrsuml+0+sumr,其中suml,sumrsuml,sumr分别是bb左端和右端的子串和。

把判断等式suml+sumr==0suml+sumr==0变成sumr==sumlsumr==-suml,发现这个可以直接找对应关系。

所以先把bb右边每个位置的和sumrsumr求出来,丢进一个mapmap,然后对左边依次求和,并且在mapmap中找到sumlsuml对应的sumrsumr,计入答案即可。

记得开long longlong\ long

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<map>
#define MAXN 100010
using namespace std;
int n,m,pos,suml=0,sumr=0,val[MAXN];
long long ans=0;
map<int,int> a;
char tp[100000],*p1=tp,*p2=tp;
inline char get_char(){
	return p1==p2&&(p2=(p1=tp)+fread(tp,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    int date=0,w=1;char c=0;
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=get_char();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=get_char();}
    return date*w;
}
void work(){
    for(int i=pos;i<=n;i++){
        if(val[i]<m)sumr--;
        if(val[i]>m)sumr++;
        a[sumr]++;
    }
    for(int i=pos;i>=1;i--){
        if(val[i]<m)suml--;
        if(val[i]>m)suml++;
        ans+=a[-suml];
    }
    printf("%lld\n",ans);
}
void init(){
    n=read();m=read();
    for(int i=1;i<=n;i++){
        val[i]=read();
        if(val[i]==m)pos=i;
    }
}
int main(){
    init();
    work();
    return 0;
}