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;
}
posted @ 2021-12-30 17:42  Point_King  阅读(112)  评论(0编辑  收藏  举报