标签: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