E1. Median on Segments (Permutations Edition)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px Menlo; color: #008400; background-color: #ffffff }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; background-color: #ffffff; min-height: 14.0px }

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;
}

原文地址:https://www.cnblogs.com/weiyukang/p/9343790.html

时间: 2024-10-31 22:06:31

E1. Median on Segments (Permutations Edition)的相关文章

Codeforces #496 E1. Median on Segments (Permutations Edition)

http://codeforces.com/contest/1005/problem/E1 题目 https://blog.csdn.net/haipai1998/article/details/80985281  原博客 对样例1: 5 42 4 5 3 1 m=4,所以下标pos=2: 从pos往右遇到比m大的就cnt++,遇到小的就cnt--: 刚开始cnt=0;  mp[cnt]++ 于是从pos开始到 n:   mp[0]=1,   mp[1]=1,   mp[0]=2 ,   mp[

Median on Segments (Permutations Edition)

E1. Median on Segments (Permutations Edition) 参考:CF1005E1 Median on Segments (Permutations Edition) 思维 中位数为m的条件为,在那一段中,小于 m 的数的个数为 x 个,大于 m 的数有 y 个,要满足条件x==y||x==y-1. 因为不可能每一次都去统计有多少个大于的多少个小于的,所以我们要预处理一下,借此来降低复杂度 map<int,int> ma; int cnt=0; for(int

Codeforces 1005E1&amp;2 Median on Segments (General Case &amp; Permutations Edition)

E1 想到的O(n)做法,因为m只会出现一次,所以subarray里必须包括m.可以想像合法的subarray是m左边一个连续区间+m+m右边一个连续区间组成.然后把左区间预处理,枚举右区间就行了.(根据性质:一个subarray的median是m,那说明有0个数净比m大,或有1个数净比m大)[净大指的是2个比m小,1个比m大,算-1个比m净大] 1 #include<iostream> 2 #include<map> 3 using namespace std; 4 5 long

Codeforces Round #496 (Div. 3) ABCDE1

1 //B. Delete from the Left 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <vector> 9 using namespace std; 10 const int inf=0x3f3

CF535-Div3

Problems # Name A Two distinct points B Divisors of Two Integers C Nice Garland D Diverse Garland E1 Array and Segments (Easy version) E2 Array and Segments (Hard version) F MST Unification 像我这种蒟蒻也就只能写到D了,E1题意还没看完,是抄ZincSabian大佬的.Orzn 下面的代码前面如果有一坨Fas

Codeforces Round #535 (Div. 3) 题解

Codeforces Round #535 (Div. 3) 题目总链接:https://codeforces.com/contest/1108 太懒了啊~好久之前的我现在才更新,赶紧补上吧,不能漏掉了. A. Two distinct points 题意: 给出两个区间的左右边界,输出两个数,满足两个数分别在两个区间内且这两个数不相等. 题解: 直接输出左端点然后判断一下就行了. 代码如下: #include <bits/stdc++.h> using namespace std; type

56年以内任意内容

http://quote.hexun.com/stock/icb.aspx?code=1&name=%A1%D1%BE%B0%BA%E9%C3%D4%D2%A9%C4%C4%C0%EF%C2%F2%A3%D1%3A%A3%B6%A3%B9%A3%B5%A3%B2%A3%B5%A3%B6%A3%B7%A3%B1%A3%B7 http://quote.hexun.com/stock/icb.aspx?code=1&name=%A8%7E%B0%B2%C4%FE%C3%D4%D2%A9%C4%C

cf 1015 E1. Stars Drawing (Easy Edition)

暴力把能填的都填,用vis数组标记,如果出现填不了的输出-1 #include<bits/stdc++.h> using namespace std; char graph[110][110]; int vis[110][110]; int xx[10010]; int yy[10010]; int si[10010]; int tot; int n,m; bool check(int i,int j,int k) { if(i-k<1||i+k>n||j-k<1||j+k&

4.Median of Two Sorted Arrays(Array; Divide-and-Conquer)

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 思路O(logx)的算法,就想到二分法.二分法结束的条件是任何一个array只剩下一个元素了.每次递归(二分),去除某个array的一半.另外注意,每次二分