概述
题目传送门
题意: 给你n(n<=1e5)个互不相同的数,给你一个数m,问你m在多少个连续子序列中是中位数,对于序列长度为偶数的情况,中位数取左边那个。
思路: 先找到m在序列中的位置,然后从这个位置开始向左跑到1(先向右跑到n也可以。),如果a[i]>m,就cnt++,a[i]<m则cnt–,用个map记录,每次ma[cnt]++。所以cnt表示的是大于m的数的个数和小于m的数的个数的差值,跑完这边之后,把cnt置为0,然后扫另一边,开始统计答案,统计的是ma[-cnt]和ma[-cnt+1]。
#include<bits/stdc++.h>
#define endl 'n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define vi vector<int>
#define mii map<int,int>
#define pii pair<int,int>
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=2e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-6;
int a[N];
signed main()
{
int n,m;
cin>>n>>m;
map<int,int>ma;int pos;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]==m)
pos=i;
}
int cnt=0;
for(int i=pos;i>=1;i--)
{
if(a[i]>m)
cnt++;
else if(a[i]<m)
cnt--;
ma[cnt]++;
}
cnt=0;
int res=0;
for(int i=pos;i<=n;i++)
{
if(a[i]>m)
cnt++;
else if(a[i]<m)
cnt--;
res+=ma[-cnt];
res+=ma[-cnt+1];
}
cout<<res<<endl;
}
最后
以上就是辛勤蚂蚁为你收集整理的E1. Median on Segments(找一个数在多少个连续子序列中是中位数)的全部内容,希望文章能够帮你解决E1. Median on Segments(找一个数在多少个连续子序列中是中位数)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复