一开始没看到是1-n的排列,死活不会做。。既然b只有一个位置就好办嘛。。把小于b的数置为-1,大于b的数置为1,b置为0,然后处理出前缀和。。再分别处理出从b往前和往后的序列中和为k的数量,然后乘法原理乱搞一下。。注意这里和会有负数,要处理一下,然后和为0要特殊处理。。
#include<iostream>
#include<cstdio>
#include<memory.h>
#define maxn 100005
#define ll long long
using namespace std;
int n,b,i,q,pos,sum[maxn],a[maxn*2],c[maxn*2],*pre=a+maxn,*suf=c+maxn;
ll ans=0;
int main()
{
freopen("1303.in","r",stdin);
scanf("%d%d",&n,&b);
sum[0]=0;
for (i=1;i<=n;i++)
{
scanf("%d",&q);
if (q==b) q=0,pos=i;
else if (q>b) q=1;
else q=-1;
sum[i]=sum[i-1]+q;
}
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
for (i=pos-1;i;i--) pre[sum[pos-1]-sum[i-1]]++;
for (i=pos+1;i<=n;i++) suf[sum[i]-sum[pos]]++;
for (i=-n;i<=n;i++) if (i) ans+=(ll)pre[i]*suf[-i];
cout<<ans+(ll)(pre[0]+1)*(suf[0]+1);
}