题意:
给你一个区间,让你把区间分成连续的4份,他们各自元素总和。【最大的减去最小的】要最小。
问你最小差值。
POINT:
区间为ABCD。
把AB所在的区间称为左区间。CD为右区间。
把左区间尽量分成平均的2分。右区间也一样。
这样枚举n个答案。然后取最小就行了。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 2e5+33;
#define LL long long
LL a[maxn],b[maxn];
void f(LL a,LL b,LL &Max,LL &Min)
{
if(a==0||b==0) return;
Max=max(Max,a);
Max=max(Max,b);
Min=min(Min,a);
Min=min(Min,b);
}
LL ff(LL x,LL be,LL ed)
{
LL sum=b[ed]-b[be-1];
LL aim=sum/2+b[be-1];
LL k=x;
LL ju=abs(aim-b[x]);
if(x-1>=be&&ju>abs(aim-b[x-1]))
{
ju=abs(aim-b[x-1]);
k=x-1;
}
if(x+1<ed&&ju>abs(aim-b[x+1])){
k=x+1;
}
return k;
}
int main()
{
LL n;
scanf("%lld",&n);
for(LL i=1;i<=n;i++){
scanf("%lld",&a[i]);
b[i]=b[i-1]+a[i];
}
LL ans=1e18;
for(LL i=2;i<=n-2;i++){
LL Max=0;
LL Min=1e18;
LL aim=b[i]/2;
LL to=lower_bound(b+1,b+1+i,aim) - b;
if(to==i) to--;
to=ff(to,1,i);
f(b[to],b[i]-b[to],Max,Min);
aim=(b[n]-b[i])/2+b[i];
to=lower_bound(b+i+1,b+n+1,aim) - b;
if(to==n) to--;
to=ff(to,i+1,n);
f(b[to]-b[i],b[n]-b[to],Max,Min);
ans=min(ans,Max-Min);
}
printf("%lld\n",ans);
}