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[-1]=1;

接下来从pos向左, 遇到比m大的就cnt-- ,遇到比小的就cnt++ , 刚开始cnt=0

因为n为偶数时m要排在n/2 ,n为奇数时m要排在n/2+1;

所以  ans += mp[cnt] + mp[cnt+1]     比如i=pos时候,此时cnt=0, ans+=mp[0]+mp[1] (偶数的情况加上奇数的情况)

i=pos-1,即cnt=1,a[i]=2的时候,ans+=mp[1]+mp[2] (mp[1]即加到5的位置)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <cctype>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<string>
 8 #include<cmath>
 9 #include<set>
10 #include<vector>
11 #include<stack>
12 #include<queue>
13 #include<map>
14 using namespace std;
15 #define ll long long
16 #define mem(a,x) memset(a,x,sizeof(a))
17 #define se second
18 #define fi first
19 const int INF= 0x3f3f3f3f;
20 const int N=2e5+5;
21
22 int n,m,pos,a[N];
23 map<int,ll> mp;
24
25 int main()
26 {
27     cin>>n>>m;
28     for(int i=1;i<=n;i++){
29         scanf("%d",&a[i]);
30         if(a[i]==m) pos=i;
31     }
32     int num=0,cnt=0;
33     for(int i=pos;i<=n;i++)
34     {
35         if(a[i]>m) cnt++;
36         if(a[i]<m) cnt--;
37         mp[cnt]++;
38     }
39     num=0,cnt=0;
40     ll ans=0;
41     for(int i=pos;i>=1;i--)   // 2 4 5 3 1
42     {
43         if(a[i]<m) cnt++;
44         if(a[i]>m) cnt--;
45         ans+=mp[cnt]+mp[cnt+1];
46     }
47     cout<<ans;
48 }

原文地址:https://www.cnblogs.com/thunder-110/p/9482094.html

时间: 2024-08-30 11:29:12

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

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 奇数

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

Educational Codeforces Round 10 D. Nested Segments (树状数组)

题目链接:http://codeforces.com/problemset/problem/652/D 给你n个不同的区间,L或者R不会出现相同的数字,问你每一个区间包含多少个区间. 我是先把每个区间看作整体,按照R从小到大排序.然后从最小的R开始枚举每个区间,要是枚举到这个区间L的时候,计算之前枚举的区间有多少个Li在L之后,那么这些Li大于L的区间的数量就是答案.那我每次枚举的时候用树状数组add(L , 1) 说明在L这个位置上出现了区间,之后枚举的时候计算L之前的和,然后i - 1 -

CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点值离散化,按照左端点从大到小排序,顺着这个顺序处理所有线段,那么满足在它内部的线段一定是之前已经扫到过的.用树状数组判断有多少是在右端点范围内. 1 #include <iostream> 2 #include <vector> 3 #include <algorithm>

【CodeForces】901 C. Bipartite Segments

[题目]C. Bipartite Segments [题意]给定n个点m条边的无向连通图,保证不存在偶数长度的简单环.每次询问区间[l,r]中包含多少子区间[x,y]满足只保留[x,y]之间的点和边构成的图是一个二分图. [算法]Tarjan缩点(找环) [题解]如果两个奇数长度的环相交,会得到一个偶数长度的简单环.所以原图是不存在偶数长度环的仙人掌(每条边只属于一个简单环). 二分图的定义:一个图是二分图当且仅当不存在奇数长度的环.在当前仙人掌上,二分图实际上要求选择的点不存在环. 也就是对于

codeforces 430 A Points and Segments (easy)

题意:给出n个点,m个区间,需要给这些点涂上蓝色或者红色,使得每个区间里面的点的红色的点的个数与蓝色的点的个数的差值小于1 唉,题目的标题就标注了一个easy= = 最开始做的时候对点还有区间都排序了,模拟来做,可是错了 后来发现不管区间怎么样,只要红色和蓝色交替涂色, 就一定能满足“使得每个区间里面的点的红色的点的个数与蓝色的点的个数的差值小于1 ”这个条件 有点像上次做的cf交替输出奇数偶数那个A题 1 #include<iostream> 2 #include<cstdio>

Codeforces Round #535 E2-Array and Segments (Hard version)

题意: 给你一个数列和一些区间,让你选择一些区间(选择的区间中的数都减一), 求最后最大值与最小值的差值最大,并输出选择的区间 思路: 在n=300的时候,我们是枚举每个数作为最小值,应用所有覆盖它的区间,并且没 次都更行差值的最大值. 但是这里的n=1e5,所以我们不能用O(n*n*m),但是我们看到这里的m=300 所以可以从m入手,枚举区间,就是记录每个区间的两个端点,利用差分的思想, 来枚举更新最大值 这里说一下为什么枚举最小值,因为如果最大值也在这个区间则抵消,如果没在则 更好 #in

Codeforces 1249 D2. Too Many Segments (hard version)

传送门 贪心 对于第一个不合法的位置,我们显然要通过删除几个覆盖了它的区间来使这个位置合法 显然删右端点更靠右的区间是更优的,所以就考虑优先删右端点靠右的,然后再考虑下一个不合法位置 用一个 $set$ 维护一下右端点和区间编号即可 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector