Luogu P1627 中位数

Luogu P1627 中位数

先记录目标数的位置,并且把数组映射为:
$$a[i]=\begin{cases}-1,a[i]<b\0,a[i]=b\1,a[i]>b\end{cases}$$
然后分别求一个左边和右边的部分和,注意到下标可能为负,所以要数组整体向右偏移$n$。

#include<bits/stdc++.h>
#define N 100010

using namespace std;

int n,b,pos;
int a[N],sum[N],lsum[N*2],rsum[N*2];
long long ans;

void Read() {
	scanf("%d%d",&n,&b);
	for(int i=1;i<=n;i++) {
		scanf("%d",&a[i]);
		if(a[i]==b) {
			pos=i;
			a[i]=0;
			continue;
		}
		a[i]<b?a[i]=-1:a[i]=1;
	}
	return;
}

void Solve() {
	lsum[n]=1;
	rsum[n]=1;
	for(int i=pos-1;i>=1;i--) {
		sum[i]=sum[i+1]+a[i];
		lsum[sum[i]+n]++;
	}
	for(int i=pos+1;i<=n;i++) {
		sum[i]=sum[i-1]+a[i];
		rsum[sum[i]+n]++;
	}
	for(int i=0;i<=n*2;i++) {
		ans+=lsum[i]*rsum[n*2-i];
	}
	printf("%lld",ans);
	return;
}

int main()
{
	Read();
	Solve();
	return 0;
}
posted @ 2019-10-26 18:13  WalkerV  阅读(121)  评论(0编辑  收藏  举报