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

输入格式
第一行为两个正整数n和b,第二行为1~n的排列。

【数据规模】

对于30%的数据中,满足n≤100;

对于60%的数据中,满足n≤1000;

对于100%的数据中,满足n≤100000,1≤b≤n。

输出格式
输出一个整数,即中位数为b的连续子序列个数。

输入输出样例
输入 #1复制

7 4
5 7 2 4 3 1 6

输出 #1复制
4


我们其实并不关心数字的大小,而是只关心相对大小,因为我们选的区间长度为奇数。于是我们把大于b的当成1,b为0,小于b的为-1.

我们考虑枚举左端点,从pos-1开始到1,pos为数字b 的位置。

枚举的同时我们计算和为s,对于当前这个端点的贡献就是pos右边和为-s的个数(可以仔细思考一下)。

然后我们漏掉了pos作为左右区间的时候,和单独一个数字的时候。然后就可以了。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,b,a[N],res,pos,l[N<<1],r[N<<1],base=1e5,s;
signed main(){
	cin>>n>>b;
	for(int i=1;i<=n;i++)	cin>>a[i],a[i]=(a[i]==b?0:(a[i]>b?1:-1));
	for(int i=1;i<=n;i++)	if(!a[i])	pos=i;
	for(int i=pos-1;i>=1;i--)	s+=a[i],l[s+base]++; s=0;
	for(int i=pos+1;i<=n;i++)	s+=a[i],r[s+base]++; s=0;
	for(int i=pos-1;i>=1;i--)	s+=a[i],res+=r[base-s];
	res+=l[base]+r[base]+1;
	cout<<res<<endl;
	return 0;
}