题目描述真简单:给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。
n<100000;n^2过不去了,甚至说答案每次加一,都不行,答案应该会有一定的规律,满足乘法的性质
而不是一次一次的加法,首先找到d的位置pos,向左扫,记录到一个位置时比他大的和比他小的差值,
然后x【差值】++,右边改成记录比他小和比他大的差值,y【差值】++;
如果差值一样,但是差值的表向是相反的,那么他们就能以d为中位数算一个区间,而又因为
假设,左边差值k的区间有2个,右边差值为2的区间有3个,两两组合,ans+=2*3;
总之,智商题
需要注意的是c++的数组不能为负,那么就以正代负了,重新找个原点喽~
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int d,n,a[100009],pos,x[300009],y[300009];
int main()
{
scanf("%d%d",&n,&d);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]==d) pos=i;
}
int ans=0;
int k=0;
x[n]=1;y[n]=1;
for (int j=pos-1;j>=1;j--)
{
if (a[j]>d) k++;else k--;
x[k+n]++;
}
k=0;
for (int j=pos+1;j<=n;j++)
{
if (a[j]<d) k++;else k--;
y[k+n]++;
}
for (int j=0;j<=2*n;j++) ans+=x[j]*y[j];
printf("%d",ans);
return 0;
}