链接:https://ac.nowcoder.com/acm/contest/949/D
来源:牛客网
题目描述
水果店里有 nn个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 aiai,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 0 即可),他就满意了。
小阳想知道在他满意的条件下最多能买多少个水果。
你能帮帮他吗?
输入描述:
第一行输入一个正整数 n,表示水果总数。
第二行输入 n 个整数 aiai,表示小阳对每个水果的喜爱程度。
输出描述:
一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
#include<bits/stdc++.h>
using namespace std;
int dp[2000005];
int tree[2000005<<2];
void build(int root,int l,int r){
if(l==r){
tree[root]=dp[l];
return ;
}
int mid=l+r>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
tree[root]=min(tree[root<<1],tree[root<<1|1]);
}
int query(int root,int l,int r,int q){//找到一个比查询节点小 且距离查询点最远的左边的结点 二叉判别树
if(l==r)return l;
int mid=l+r>>1;
if(tree[root<<1]<q)return query(root<<1,l,mid,q);
return query(root<<1|1,mid+1,r,q);
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
dp[i]=dp[i-1]+t;
}
build(1,1,n);
int ans=0;
for(int i=1;i<=n;i++){
if(dp[i]>0)ans=max(i,ans);
else if(dp[i]!=tree[1]){//当前不是最小节点 才能找到一个比当前节点小 且最远的点
ans=max(i-query(1,1,n,dp[i]),ans);
}
}
cout<<ans<<endl;
return 0;
}