1. 程式人生 > >E1. Median on Segments (Permutations Edition)

E1. Median on Segments (Permutations Edition)

ont -h 意思 std lld 中間 margin 一個 segments

n個數字 不重復 給你一個m

然後問你有多少個區間的中位數是m

奇數區間選中間那個

偶數區間選中間偏左那個

因為是一個區間

肯定包含m這個數字

然後我們從m右邊開始 記錄從m到右邊的每個數字這段區間比他大小的數字有多少個 用map記錄一下

比如說

5 4

2 4 5 3 1

從4開始

2 4 5 3 1

mp[0] = 1 mp[1] = 1 mp[0] = 2 mp[-1] = 1;

4:mp[0] = 1 從4到4這個區間比4大的數或者小的數一共有0個

5:mp[1] = 1 從4到5這個區間比4大的數有一個 則 mp[1] = 1 然後我們就可以從左邊去匹配啦

3:mp[0] = 2 從4到3這個區間 比4大的數有一個 比4小的數有一個 所以mp[0]++ mp[0]=2

1:mp[-1] = 1 從4到1這個區間 比4大的有一個 比4小的有一個 所以mp[-1] = 1 因為我們不是要去湊中位數嘛

然後去從4開始去找左邊 然後去匹配右邊的map

4的話 4到4 比4大小的數一共有0個 則 ans += mp[0] ans = 2

mp[0] = 2 [4,4] [4,5,3]

然後ans += mp[1] 因為還有區間的個數是偶數的情況 偶數的意思就是 比m大的數比 比m小的數 多1

ans = 3

2 4到2 比4小的數有一個

ans += mp[- * -1] = mp[1] 因為左邊比4小的數有一個 所以去4的右邊找一個從4開始的區間比4大的數字只有一個的區間 ans = 4

然後去考慮偶數

ans += mp[-1*-1 + 1] = mp[2]

ans = 4

#include <stdio.h>
#include <map>
using namespace std;
typedef long long ll;
int n, m;
const int maxn = 2e5 + 5;
map<int, int>mp;
int pos, a[maxn];
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if(a[i] == m) pos = i;
    }
    int cnt = 0;
    for(int i = pos; i <= n; i++) {
        if(a[i] > m) cnt++;
        else if(a[i] < m) cnt--;
        mp[cnt]++;//記錄右邊比m大小的情況  從pos 到 i 這一段比m大小的情況
    }
    ll  ans = 0;
    cnt=0;
    for(int i = pos; i >= 1; i--) {
        if(a[i] > m) cnt++;
        else if(a[i] < m) cnt--;
        ans += 1LL*mp[-cnt];//奇數取最中間
        ans += 1LL*mp[-cnt + 1];//偶數去中間靠左的
    }
    printf("%lld\n", ans);//註意會爆int
    return 0;
}

E1. Median on Segments (Permutations Edition)