HDU 4908 BestCoder Sequence(BestCoder Round #3)

Problem Description:

Mr Potato is a coder.
Mr Potato is the BestCoder.

One night, an amazing sequence appeared in his dream. Length of this sequence is odd, the median number is M, and he named this sequence as Bestcoder Sequence.

As the best coder, Mr potato has strong curiosity, he wonder the number of consecutive sub-sequences which are bestcoder sequences in a given permutation of 1 ~ N.

Input:

Input contains multiple test cases. 
For each test case, there is a pair of integers N and M in the first line, and an permutation of 1 ~ N in the second line.

[Technical Specification]
1. 1 <= N <= 40000
2. 1 <= M <= N

Output:

For each case, you should output the number of consecutive sub-sequences which are the Bestcoder Sequences.

Sample Input:

1 1

1

5 3

4 5 3 2 1

Sample Output:

1

3

Hint:

For the second case, {3},{5,3,2},{4,5,3,2,1} are Bestcoder Sequence.

题意:有一个1~n的序列,现在我们要找到这个序列以m为中位数(eg:1 2 3 4 5 || 5 4 3 2 1,这是两个以3为中位数的序列)的连续子序列有多少个。

这里先来看一下1 2 3 4 5这个序列,首先我们可以得到它的sum值(请结合下面的代码来看):

a[i]         1      2      3      4      5

sum[i]    -1    -2     -2     -1     0

由于我们下标都是从1开始的,那么我们可以加上a[0]和sum[0],变成

a[i]         0      1      2      3      4      5

sum[i]    0      -1    -2     -2     -1     0

离散化之后(变成正数,便于模拟,这里假如加上的是40000)

a[i]                         0             1           2           3            4          5

sum[i]                    0            -1          -2          -2          -1          0

sum[i]+40000     40000     39999    39998    39998    39999    40000

首先从0~x-1遍历,这时b[40000] = 1, b[39999] =1, b[39998]=1;那我们在遍历x~n时由上面分析得也会遇见这三个值,那么我们最终就会发现满足条件的序列就是三个。(注意b数组的下标是sump[i]+40000)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
using namespace std;

const int N=1e6+10;
const int M=50000;
const int INF=0x3f3f3f3f;
int a[N], sum[N], b[N]; 

int main ()
{
    int n, m, i, x, ans;

    while (scanf("%d%d", &n, &m) != EOF)
    {
        memset(sum, 0, sizeof(sum));
        memset(b, 0, sizeof(b));
        ans = 0;

        for (i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);

            sum[i] = sum[i-1];
            if (a[i] < m) sum[i]--; ///比中位数小--
            if (a[i] > m) sum[i]++; ///比中位数大++

            if (a[i] == m)
                x = i;
        }

        for (i = 0; i < x; i++)
            b[sum[i]+M]++; ///由于我们的sum值可能是负数,那么我们需要将所有的数变成正数,为了结果不受影响,加上一个比较大的数

        for (i = x; i <= n; i++)
            ans += b[sum[i]+M]; ///首先我们要明白当两个位置的sum值相等时,那么这中间就会产生一个符合题意的序列

        printf("%d\n", ans);
    }

    return 0;
}
时间: 2024-10-14 04:53:00

HDU 4908 BestCoder Sequence(BestCoder Round #3)的相关文章

HDU 4390 Number Sequence (容斥原理+组合计数)

HDU 4390 题意: 大概就是这样.不翻译了: Given a number sequence b1,b2-bn. Please count how many number sequences a1,a2,...,ansatisfy the condition thata1?a2?...?an=b1?b2?-?bn(ai,bi>1). 思路: 我们能够确定一件事:等号两边由同样数量的质因子组成. 假设ai能够等于1,答案就是把这些质因子分配进n个位置的方案数. 设左边的数字共由x个质因子组成

hdu 5014 Number Sequence(意淫题)

Number Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 545    Accepted Submission(s): 258 Special Judge Problem Description There is a special number sequence which has n+1 integers. F

HDu 5950 Recursive sequence(矩阵快速幂)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1323    Accepted Submission(s): 589 Problem Description Farmer John likes to play mathematics games with his N cows. Recently,

HDU - 6025 Coprime Sequence(gcd+前缀后缀)

Do you know what is called ``Coprime Sequence''? That is a sequence consists of nnpositive integers, and the GCD (Greatest Common Divisor) of them is equal to 1. ``Coprime Sequence'' is easy to find because of its restriction. But we can try to maxim

NYOJ 427 &amp; HDU 1005 Number Sequence(找循环节)

[题目链接]click here~~ [题目大意]已经 f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.求f(n), [解题思路]:此题是大三届的一场比赛题,前几天做了下,结果是不忍直视啊,wa了几乎一页了,最开始想的是用矩阵快速幂,但是想了想,取模数才不到10,7 7=49,也就是说最大结果不超过49种可能,直接模拟递推式试试,结果发现不行,后来想到了用循环节,不难想到: 如果结果有两个答案连着 =1,则后面的全部和

hdu 5306 Gorgeous Sequence(暴力线段树)(好题)

题意:区间最大长度为1000000, 三种操作: 区间求和: 区间求最大值: 将节点值更新为当前值与给定值中的最小值(有趣的更新): 思路: 暴力线段树.关键在于处理标记,需要维护最大标记,标记覆盖范围,所在区间: 覆盖区域标记起到很关键的作用: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node{ long long sum; int tag,m

HDU 4908 (杭电 BC #3 1002题)BestCoder Sequence(DP)

题目地址:HDU 4908 这个题是从m开始,分别往前DP和往后DP,如果比m大,就比前面+1,反之-1.这样的话,为0的点就可以与m这个数匹配成一个子串,然后左边和右边的相反数的也可以互相匹配成一个子串,然后互相的乘积最后再加上就行了.因为加入最终两边的互相匹配了,那就说明左右两边一定是偶数个,加上m就一定是奇数个,这奇数个的问题就不用担心了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h&g

HDU 4908 BestCoder Sequence(组合数学)

HDU 4908 BestCoder Sequence 题目链接 题意:给定一个序列,1-n的数字,选定一个作为中位数m,要求有多少连续子序列满足中位数是m 思路:组合数学,记录下m左边和右边一共有多少种情况大于m的数字和小于n数组的差,然后等于左边乘右边所有的和,然后最后记得加上左右两边差为0的情况. 当时也是比较逗,还用树状数组去搞了,其实完全没必要 代码: #include <cstdio> #include <cstring> #define lowbit(x) (x&am

hdu4908 &amp; BestCoder Round #3 BestCoder Sequence(组合数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4908 BestCoder Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 618    Accepted Submission(s): 214 Problem Description Mr Potato is a code