考察:
思维题
思路:
b如果是中位数,那么左边比它小的数要等于右边比它大的数。
那么这样就已经满足了子序列长度为奇数。
接下来考虑选择中位数b所在位置,统计它前面的数的后缀和,后面的数
的前缀和。答案就累计后缀和等于前缀和的个数。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int n,b,a[N],num[N];
int main(){
scanf("%d%d",&n,&b);
int j;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]<b) a[i]=-1;//小于b记为-1
if(a[i]>b) a[i]=1;//大于b记为1
if(a[i]==b) j=i;//如果是中位数,记录下位置
}
int sum=0,ans=1;//一个中位数自己也算一个连续子序列,所以ans=1
for(int i=j-1;i>=1;i--){//记录中位数左边的后缀和为sum的个数
sum+=a[i];
num[sum]++;
if(!sum) ans++;//如果sum==0,表明是连着的中位数,那么每个中位数自身都算一个连续子序列,ans++
}
sum=0;//记住清0
for(int i=j+1;i<=n;i++){//记录右边的前缀和
sum+=a[i];
ans+=num[-sum];//顺便累计答案了,左边是x,那么右边需要是-x
if(!sum) ans++;//如果sum==0,表明是连着的中位数,那么每个中位数自身都算一个连续子序列,ans++
}
cout<<ans<<endl;
return 0;
}