标签:des style blog http color java os io
1 1 1 5 3 4 5 3 2 1
1 3HintFor the second case, {3},{5,3,2},{4,5,3,2,1} are Bestcoder Sequence.
题解及代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <string>
using namespace std;
struct node
{
int l[40100],z,h[40100]; //l记录小于m的数的个数,h记录大于m的数的个数,
//z记录大于m和小于m的数个数相等的个数
//当然这些是连续子串大于m和小于m抵消之后的数的个数
}l,r; //l记录m左边的,r记录m右边的情况
int root[40010];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int p=-1;
l.z=0;r.z=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&root[i]);
l.l[i]=0;l.h[i]=0;
r.l[i]=0;r.h[i]=0;
if(root[i]==m) p=i;
}
int sum=0;
for(int i=p;i>=1;i--)
{
if(root[i]==m) sum+=0;
else if(root[i]<m) sum-=1;
else sum+=1;
if(sum==0) l.z++;
else if(sum<0) l.l[-sum]++;
else l.h[sum]++;
}
sum=0;
for(int i=p;i<=n;i++)
{
if(root[i]==m) sum+=0;
else if(root[i]<m) sum-=1;
else sum+=1;
if(sum==0) r.z++;
else if(sum<0) r.l[-sum]++;
else r.h[sum]++;
}
int ans=0;
ans=l.z*r.z;
for(int i=1;i<=m;i++)
{
ans+=(l.l[i]*r.h[i]);
ans+=(l.h[i]*r.l[i]);
}
printf("%d\n",ans);
}
return 0;
}
/*
本题的要求是求出一段1-N的序列中以m为中位数的子序列的个数,要求序列长度为奇数。
因为是中位数,所以大于m和小于m的数各占一半,所以如果存在那么必然长度为奇数,所以
直接考虑怎么构造就可以了。
我们可以想到,大于m的数和小于m的数成为一对可以抵消,那么我们把m的位置先找出来,
然后枚举m位置左边大于m的数有多少,小于m的数有多少(抵消之后),和右边大于m的数有多
少,小于m的数有多少(抵消之后),以及等于0的个数有多少。
那么我们最后把左边大于m的个数与右边小于m的个数对应相乘,右边大于m的个数与左边小于
m的个数对应相乘,以及0的个数相乘,就能得到组后结果。
*转载请注明出处,谢谢。
*/
hdu 4908 BestCoder Sequence,布布扣,bubuko.com
标签:des style blog http color java os io
原文地址:http://blog.csdn.net/knight_kaka/article/details/38379969