【bzoj1303】[CQOI2009]中位数图
一个大于b的数和一个小于b的数可以互相抵消,所以我们用1和-1表示。
从b向两边扩展,left[i]表示b左边抵消后有i个数比b小的可能数,right[i]表示b右边抵消后有i个数比b大的可能数。
ans=sigma(left[i]*right[i]).
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define N 200010 int n,b,k; int ans; int a[N]; int l[N],r[N],sum[N]; int main() { scanf("%d%d",&n,&b); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); if (a[i]==b) k=i,a[i]=0; else a[i]=a[i]>b ? 1 : -1; } l[n]=1; r[n]=1; for (int i=k-1;i>=1;i--) { sum[i]=sum[i+1]+a[i]; l[sum[i]+n]++; } for (int i=k+1;i<=n;i++) { sum[i]=sum[i-1]+a[i]; r[sum[i]+n]++; } for (int i=1-n;i<=n-1;i++) ans+=l[i+n]*r[(n<<1)-(i+n)]; printf("%d",ans); return 0; }