其他分享
首页 > 其他分享> > 牛客 [CQOI2009]中位数图

牛客 [CQOI2009]中位数图

作者:互联网

题目链接:https://ac.nowcoder.com/acm/problem/19913

因为是中位数的位置,所以可以不考虑其他数字是什么,只需要知道相对大小即可

那么让大于b的数变为1 小于b的数变为-1 等于b的数变为0

第一反应是求了前缀和 然后却只能n^2 求每个区间来判断是否满足条件 显然会T

正解应该是以 0为中心 对0的左边求一次后缀和 对0的右边求一次前缀和  这样是为了确保是一段连续的子序列

然后 先记录右边的前缀和 为i 的有多少个  再去遍历左边的后缀和  当左边后缀和为i时 找刚刚记录的前缀和有多少个-i ,-i就是贡献度

而如果是0的话 本身也可以++ 0的话除了只有b本身之外 一定是偶数个 那么+上b就是奇数个

同理 两边 的前缀和和后缀和 相加也一定是偶数个  那么加上b本身也是奇数个 所以奇数的问题就不用考虑了

时间复杂度 o(n)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =2e5+10;
 6 const int mod=1e9+7;
 7 int a[maxn];
 8 int main()
 9 {
10     ios::sync_with_stdio(false);
11     cin.tie(0);
12     int n,b;
13     cin>>n>>b;
14     int mid;
15     for(int i=1;i<=n;i++)
16     {
17         cin>>a[i];
18         if(a[i]==b)
19             mid=i,a[i]=0;
20         else if(a[i]>b)
21             a[i]=1;
22         else
23             a[i]=-1;
24     }
25     int ans=1;
26     map<int,int>mp;
27     for(int i=mid+1;i<=n;i++)
28     {
29         a[i]+=a[i-1];
30         if(a[i]==0)
31         {
32             ans++;
33         }
34         mp[a[i]]++;
35     }
36     for(int i=mid-1;i>=1;i--)
37     {
38         a[i]+=a[i+1];
39         ans+=mp[-a[i]];
40         if(a[i]==0)
41         {
42             ans++;
43         }
44     }
45     cout<<ans<<'\n';
46 
47 
48 
49 
50 }
View Code

 

标签:后缀,前缀,奇数,int,中位数,mid,牛客,CQOI2009,ans
来源: https://www.cnblogs.com/winfor/p/13047281.html