题解:P17143 [NOI 2026] 中位数
RainRecall · · 题解
场外 vp 选手,这是六题里面唯一会的一道。
做法稍微有点诡异,如果假了告诉我。
看到神秘中位数考虑先二分一步,然后把
有一种暴力想法是我们直接设
然后它在 qoj 上得了整整
感觉特别能做,考虑继续做。观察到部分分里有
于是我们想想二分之后有没有什么智慧一些的 check 方法,发现有一种想法是我们把每个
但是再观察,发现这个时候其它的段落数最多是
稍微想一下,刚才的那个把
判掉
顺带说一下,刚才的
但是这样在
代码写的极其抽象,还没有上面说的清楚,不建议任何人观看。
::::success[代码]
#include<bits/stdc++.h>
#include "median.h"
#define N 1000005
using namespace std;
int b[N],nn,kk,d[N],s[N],f[N],lst[N];
struct BIT{
int c[N*2];
void clear(){
for(int i=1;i<=nn*2+1;++i)c[i]=-1e9;
}
void add(int x,int k){
x+=nn+1;
while(x<=nn*2+1)c[x]=max(c[x],k),x+=x&-x;
}
int ask(int x){
x+=nn+1;
int ans=-1e9;
while(x)ans=max(ans,c[x]),x-=x&-x;
return ans;
}
}A;
void init(int c,int t){
}
bool check(int mid){
for(int i=1;i<=nn;++i){
if(b[i]>=mid)d[i]=1;
else d[i]=-1;
s[i]=s[i-1]+d[i];
}
if(kk<=5){
for(int i=1;i<=nn;++i)lst[i]=-1e9;
lst[0]=0;
for(int i=1;i<=kk;++i){
A.clear();
int mx=0;
A.add(0,0);
for(int j=1;j<=nn;++j){
f[j]=max(mx,A.ask(s[j])+1);
A.add(s[j],lst[j]);
mx=max(mx,lst[j]);
}
for(int j=1;j<=nn;++j)lst[j]=f[j];
}
return f[nn]>=(kk+1)/2;
}
else{
int cnt1=0,df=0,l=0;
for(int i=1;i<=nn;++i){
if(d[i]==-1)l=1;
else{
if(l)++df,l=0;
++cnt1;
}
}
if(l)++df;
// if(mid==71){
// for(int i=1;i<=nn;++i)cout<<d[i]<<" ";cout<<'\n';
// cout<<cnt1<<" "<<df<<'\n';
// }
if(cnt1<(kk+1)/2)return 0;
int ly=0;
for(int i=1;i<nn;++i){
if(d[i]==1&&d[i+1]==1)++ly;
}
if(ly>=2)return 1;
if(ly==1&&kk%2==0)return 1;
if(kk%2&&cnt1>df||kk%2==0&&cnt1>=df)return 1;
//if(mid==71)cout<<"qwq\n";
l=0;int lst=0,fzj=0,o=-1;
for(int i=1;i<=nn;++i){
if(d[i]==-1)++l;
else{
if(l&&(!lst&&l==1||lst&&l<=2)){
if(lst&&l==1){
if(o==lst)o=i;
else o=lst;
++fzj;
}
else if(o!=lst){
++fzj;
o=i;
}
}
l=0;
lst=i;
}
}
if(l==1&&lst!=o)++fzj;
df-=fzj;
if(kk%2&&cnt1>df||kk%2==0&&cnt1>=df)return 1;
return 0;
}
}
int median(int n,int k,vector<int>a){
nn=n;kk=k;
for(int i=1;i<=n;++i)b[i]=a[i-1];
int l=1,r=n,ans;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
/*
10:22 start
0 1
80 10
42 2 11 20 37 46 33 59 31 60 32 5 49 43 14 61 6 47 51 15 12 57 18 26 34 75 67 36 52 53 8 16 68 7 39 56 74 1 29 44 70 65 4 27 78 24 45 38 73 50 35 62 72 21 63 55 69 10 9 41 76 64 22 19 77 3 30 13 80 28 48 40 71 23 54 58 79 25 66 17
*/