这种题都做不出来我是不是退化成弱智了?
首先根据题意不难发现输出的第 x x x 项 a n s x ans_x ansx 等价于找到两个区间,一个包含 x x x,一个不包含 x x x,找到两者的最小差值。
直接做的时间复杂度是 O ( n 3 log n 2 ) O(n^3\log n^2) O(n3logn2),我模拟赛打的就是这个思路。
但是其实我们可以考虑逆着维护,也就是根据区间来更新 a n s x ans_x ansx。
首先提取出所有的区间,从小到大排个序,显然相邻的两个区间除去交集之后的部分就可以拿来更新。
这里其实有几种情况,大家可以根据题目给出的性质讨论讨论,最后发现都是符合的。
所以就可以做了,时间复杂度 O ( n 3 ) O(n^3) O(n3)。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL N=505;
LL n,a[N],sum[N],ans[N],cnt,b[N];
struct node
{
LL l,r,x;
}t[N*N];
bool cmp(node x,node y)
{
return x.x<y.x;
}
LL dkabs(LL x)
{
if (x<0)return -x;
return x;
}
int main()
{
memset(ans,127,sizeof(ans));
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
for(int j=1;j<=i;j++)
{
t[++cnt]={j,i,sum[i]-sum[j-1]};
}
}
sort(t+1,t+cnt+1,cmp);
for(int i=2;i<=cnt;i++)
{
LL l1=t[i].l,l2=t[i-1].l;
LL r1=t[i].r,r2=t[i-1].r;
LL p=dkabs(sum[r2]-sum[l2-1]-sum[r1]+sum[l1-1]);
memset(b,0,sizeof(b));
for(int j=l1;j<=r1;j++)b[j]^=1;
for(int j=l2;j<=r2;j++)b[j]^=1;
for(int j=1;j<=n;j++)if(b[j])ans[j]=min(ans[j],p);
}
for(int i=1;i<=n;i++)
{
printf("%lld\n",ans[i]);
}
return 0;
}