CF1616D Keep the Average High
傻逼才用左端点排序,用最少的点覆盖所有的线段的贪心是按右端点排序的!
是按右端点排序的!!!
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
int n,x;
long long a[N],b[N];
int s[N],top=0,res=0;
struct Seg{int l,r;};
bool cmp(Seg a,Seg b){return a.r==b.r?a.l<b.l:a.r<b.r;}
vector<Seg> bag;
int solve(){
cin>>n,res=n;
for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
cin>>x;for(int i=1;i<=n;++i) a[i]-=x;
for(int i=1;i<=n;++i) b[i]=b[i-1]+a[i];
top=0,bag.clear();
for(int i=1;i<=n;++i){
int L=1,R=top,tmp=-1;
while(L<=R){
int Mid=(L+R)>>1;
if(b[i]-b[s[Mid]]<0) L=Mid+1,tmp=Mid;
else R=Mid-1;
}
// for(int j=1;j<=top;++j) printf("%d ",s[j]);
// printf("\n%d %d\n",tmp,i);
if(tmp!=-1) bag.push_back((Seg){s[tmp]+1,i});
while(top&&b[s[top]]<=b[i-1]) top--;
s[++top]=i-1;
}
sort(bag.begin(),bag.end(),cmp);
for(int i=0,lst=0;i<(int)bag.size();++i){
if(bag[i].l>lst) lst=bag[i].r,res--;
}
return printf("%d\n",res),0;
}
int main(){
int T;cin>>T;while(T--) solve();
return 0;
}