E1. Median on Segments (Permutations Edition)
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)