Live2d Test Env

CodeForces - 1005E2:Median on Segments (General Case Edition) (函数的思想)

You are given an integer sequence a1,a2,,ana1,a2,…,an.

Find the number of pairs of indices (l,r)(l,r) (1lrn1≤l≤r≤n) such that the value of median of al,al+1,,aral,al+1,…,ar is exactly the given number mm.

The median of a sequence is the value of an element which is in the middle of the sequence after sorting it in non-decreasing order. If the length of the sequence is even, the left of two middle elements is used.

For example, if a=[4,2,7,5]a=[4,2,7,5] then its median is 44 since after sorting the sequence, it will look like [2,4,5,7][2,4,5,7] and the left of two middle elements is equal to 44. The median of [7,1,2,9,6][7,1,2,9,6] equals 66 since after sorting, the value 66 will be in the middle of the sequence.

Write a program to find the number of pairs of indices (l,r)(l,r) (1lrn1≤l≤r≤n) such that the value of median of al,al+1,,aral,al+1,…,ar is exactly the given number mm.

Input

The first line contains integers nn and mm (1n,m21051≤n,m≤2⋅105) — the length of the given sequence and the required value of the median.

The second line contains an integer sequence a1,a2,,ana1,a2,…,an (1ai21051≤ai≤2⋅105).

Output

Print the required number.

Examples

Input
5 4
1 4 5 60 4
Output
8
Input
3 1
1 1 1
Output
6
Input
15 2
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
Output
97

Note

In the first example, the suitable pairs of indices are: (1,3)(1,3), (1,4)(1,4), (1,5)(1,5), (2,2)(2,2), (2,3)(2,3), (2,5)(2,5), (4,5)(4,5) and (5,5)(5,5).

题意:给定N,M,已经N个数。问有多少哥区间,排序后其中位数是M。

思路:这个序列中如果只有一个M,那么可以理由前缀和的思路求解。我们把大于M的数看成1,小于M的数看成-1,那么问题就成了有多少个区间的区间和为0或者1,直接用map搞前缀和即可。现在有多个M,那么再这么搞可能会重复。

  我们把此题用函数的思想来搞,同样的,把大于等于M的数看成1,小于M的数看成-1,令F(x)表示M=x的时候,有多少个区间和大于0。

  那么结果就是F(M)-F(M+1)。那么现在问题就算求解函数F。

对于函数F(x),把大于大于x的数转化为1,否则为-1,那么现在数列是一系列的1和-1串,记录前缀和,然后可以用树状数组搞定即可,复杂度为O(N*lgN)。

但是由于只有1和-1,我们耶可以利用其特殊性,保留有效信息,把复杂度做到O(N);now表示前缀和,delta表示前面有多个位置可以满足区间和大于0,sum[x]表示前缀和为x的个数,那么新加入一个1时,delta显然会增加sum[now]个,然后now++。 加入一个-1时,delta会减少sum[now-1]个,now--。

(此题转化为函数的思想,然后做减法,妙的。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000001;
int N,M,a[maxn],sum[maxn]; ll ans;
ll solve(int num)
{
    memset(sum,0,sizeof(sum));
    int now=N; ll res=0,delta=0; sum[now]=1;
    for(int i=1;i<=N;i++){
        if(a[i]>=num) delta+=sum[now],now++;
        else  now--,delta-=sum[now];
        res+=delta;
        sum[now]++;
    }
    return res;
}
int main()
{
    scanf("%d%d",&N,&M);
    for(int i=1;i<=N;i++) scanf("%d",&a[i]);
    printf("%I64d\n",solve(M)-solve(M+1));
    return 0;
} 

 

posted @ 2018-07-10 21:15  nimphy  阅读(287)  评论(0编辑  收藏  举报