给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。
Sample Input
7 4
5 7 2 4 3 1 6
5 7 2 4 3 1 6
Sample Output
4
HINT
第三个样例解释:{4}, {7,2,4}, {5,7,2,4,3}和{5,7,2,4,3,1,6}
N<=100000
思路:把小于中位数的数设为-1,大于的为1,等于的为0,ll=1表示该数位置在中位数的左边
sum【i】数组记录1到i数的和
统计sum[]中为0的数
如sum :1(ll) 2(ll) -1(ll) 0 -1 -1 1 0有1个
在统计sum位置左右相减为0的数又三个(方法可以通过排序做)
View Code
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct data
{
int sum;
int ll;
}s[100009];
int cmp(data a,data b)
{
if(a.sum==b.sum)
return a.ll>b.ll;
else
return a.sum<b.sum;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j,temp,ri,ok=0;
s[0].sum=0;
for(i=1;i<=n;i++)
{
scanf("%d",&temp);
if(temp==m)
{
ri=i;ok=1;
}
if(ok==0)
s[i].ll=1;
else
s[i].ll=0;
if(temp>m)
temp=1;
else if(temp<m)
temp=-1;
else
temp=0;
s[i].sum=s[i-1].sum+temp;
}
int all=0;
for(i=ri;i<=n;i++)
{
if(s[i].sum==0)all++;
}
sort(&s[1],&s[n+1],cmp);
int rr=0,ll=0;
temp=s[1].sum;
for(i=1;i<=n;i++)
{
if(temp==s[i].sum)
{
if(s[i].ll)ll++;
else rr++;
}
else
{
all+=ll*rr;
ll=0;rr=0;
temp=s[i].sum;
if(s[i].ll)ll++;
else rr++;
}
}
all+=ll*rr;
printf("%d\n",all);
}
}