Problem - D - Codeforces
题意:
思路:
首先K是1e18的范围,不能去枚举,那么就去考虑猜测结论
手推样例:
初步可以猜测,K应该取的是某个峰值
结论是,K应该取最小子段和的左端点
因为当前缀和遇到最小子段时,前缀和会变小。然后变成K的一条直线,遇到上升的子段时再上升
让K取最小子段和的左端点可以使变小的代价尽可能小
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mxn=3e5+10;
const int mxe=1e5+10;
const int mod=1e9+7;
const int Inf=1e18;
int N;
int a[mxn];
void solve(){
cin>>N;
for(int i=1;i<=N;i++) cin>>a[i];
int sum=0;
int ans=0;
int seg=0;
int mx=0;
for(int i=1;i<=N;i++){
sum+=a[i];
mx=max(mx,sum);
if(sum-mx<seg){
seg=sum-mx;
ans=mx;
}
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int __=1;cin>>__;
while(__--)solve();return 0;
}