CodeForces 1005 E1.Median on Segments (Permutations Edition) (思维->差值)

E1.Median on Segments (Permutations Edition)

You are given a permutation p1,p2,…,pn. A permutation of length n is a sequence such that each integer between 1 and n occurs exactly once in the sequence.

Find the number of pairs of indices (l,r) (1≤l≤r≤n) such that the value of the median of pl,pl+1,…,pr is exactly the given number m.

The median of a sequence is the value of the 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] then its median is 4 since after sorting the sequence, it will look like [2,4,5,7] and the left of two middle elements is equal to 4. The median of [7,1,2,9,6] equals 6 since after sorting, the value 6 will be in the middle of the sequence.

Write a program to find the number of pairs of indices (l,r) (1≤l≤r≤n) such that the value of the median of pl,pl+1,…,pr is exactly the given number m.

Input

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

The second line contains a permutation p1,p2,…,pn (1≤pi≤n). Each integer between 1 and n occurs in p exactly once.

Output

Print the required number.

Examples

Input

5 4
2 4 5 3 1

Output

4

Input

5 5
1 2 3 4 5

Output

1

Input

15 8
1 15 2 14 3 13 4 8 12 5 11 6 10 7 9

Output

48

Note

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

题意:

给n和m,然后给一组1-n的排列
问有多少个连续子序列,中位数为m

思路:

因为是排列,所以m的位置是唯一的,首先肯定是找到m的位置pos
中位数为m,则连续序列肯定包含位置pos
逆序遍历(pos-1)-1,用cnt记录大于m和小于m的数的差值,并用mark[]标记cnt出现的次数
顺序遍历(pos+1)-n,用cnt同上记录
用第二次的cnt和第一次的mark数组来找连续序列的个数:
两个位置之间的(大于-小于)差值为0或者1则满足条件

讲的不是很清楚,如果想不明白具体操作的话直接看代码就行了

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e5+5;
map<int,int>mark;
int a[maxm];
signed main(){
    int n,m;
    cin>>n>>m;
    int pos=1;//m的位置
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]==m)pos=i;
    }
    int ans=0;//答案
    int cnt=0;//大于mid的数减去小于mid的数
    mark[0]++;//pos的位置cnt为0
    for(int i=pos-1;i>=1;i--){//注意这里是从(pos-1)到1,是逆序的!
        if(a[i]>m){
            cnt++;
        }else{
            cnt--;
        }
        mark[cnt]++;
    }
    ans+=mark[0]+mark[1];//组成i-pos
    cnt=0;
    for(int i=pos+1;i<=n;i++){
        if(a[i]>m){
            cnt++;
        }else{
            cnt--;
        }
        ans+=mark[-cnt];//和小于pos的组成0
        ans+=mark[-cnt+1];//和小于pos的组成1
    }
    cout<<ans<<endl;
    return 0;
}
发布了378 篇原创文章 · 获赞 29 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/104034929