Luogu P1627 中位数
先记录目标数的位置,并且把数组映射为:
$$a[i]=egin{cases}-1,a[i]<b ,a[i]=b1,a[i]>bend{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;
}