1.
60pts
用堆来实现维护中位数。
用大跟堆维护小于中位数的数,用小跟堆维护比中位数大的数。
若两堆元素之差大于一,把中位数push进较少元素的堆,把较多元素堆的堆顶作为中位数,pop。
o(n^2log n)
#include<bits/stdc++.h> using namespace std; struct cmp1{ bool operator ()(const long long a,const long long b) const{ return a>b; } }; struct cmp2{ bool operator ()(const long long a,const long long b)const{ return a<b; } }; #define ll long long priority_queue<long long,vector<long long>,cmp2>a; priority_queue<long long,vector<long long>,cmp1>b; ll x,az,n,len,aa[200300],maxer=0; int main(){ cin>>n>>len; for(int i=1;i<=n;i++)cin>>aa[i]; for(int i=1;i<=(1+n-len);i++){ x=aa[i]; for(int j=i+1;j<=n;j++){ az=aa[j]; if(az>=x)b.push(az); else a.push(az); int s=a.size()-b.size(); if((s>1)|(s<-1)) if(a.size()>b.size()){ b.push(x); x=a.top(); a.pop(); } else{ a.push(x); x=b.top(); b.pop(); } if((j-i+1)>=len)maxer=max(maxer,x); } while(!a.empty())a.pop(); while(!b.empty())b.pop(); } cout<<maxer; return 0; }
满分做法
假设mid为中位数,我们如何验证mid为中位数是否可行呢?
即小于mid的数等于大于mid的数。
如何操作?
b[i]={0,-1,1} if(a[i]<mid)b[i]=-1; if(a[i]>mid)b[i]=1;
如果sum(i,j)=0那么这段数的中位数为mid
我们自然的想到sum()>0即是大于mid的数可能是中位数。
我们可以二分答案来查找最大满足条件的数。
用前缀和来判断mid是否可行。
复杂度o(n*logmax(a[i]))