hdu 4908 BestCoder Sequence 策略

来源:互联网 发布:全民k歌刷花软件 编辑:程序博客网 时间:2024/04/30 10:53

题意:

给定n和m,对于一个由1,2,3...,n组成的序列,问符合下列条件的子序列的个数:

1)子序列连续

2)子序列的中位数为m,

3)子序列长度为奇数

题解:

我们先找到m的位置,然后定义k=0,向左拓展,当遇到的数小于m时k++,否则k--,用f[0][i]存储各种k的出现次数(为了保证非负i=k+maxn);同理向右拓展,当遇到的数小于m时k--,否则k++,用f[1][i]存储k出现的次数。那么结果就是ans=∑(f[0][i]*f[1][i])(maxn-n<=i<=maxn+n)


代码:

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <iostream>#include <algorithm>#include <vector>#include <map>#include <queue>#include <stack>using namespace std;const int maxn=4e4+10;int a[maxn],c[maxn],f[2][maxn*2];int main(){    //freopen("D:\\in.txt","r",stdin);    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(f,0,sizeof(f));        int i,j,k=0,flag=0,x;        for(i=0;i<n;i++)        {            scanf("%d",&a[i]);            if(a[i]==m)x=i;        }        k=0;        i=x+1;        f[1][maxn]=f[0][maxn]=1;        for(;i<n;i++)        {            if(a[i]>m)k++;            else k--;            f[0][k+maxn]++;        }        i=x-1;        k=0;        for(;i>=0;i--)        {            if(a[i]>m)k--;            else k++;            f[1][k+maxn]++;        }        int ans=0;        for(i=-n;i<=n;i++)        {            ans+=f[0][i+maxn]*f[1][i+maxn];        }        printf("%d\n",ans);    }    return 0;}


0 0