I. Distance(2018焦作区域赛)

I. Distance

time limit per test

6.0 s

memory limit per test

1024 MB

input

standard input

output

standard output

There are nn points on a horizontal line, labelled with 11 through nn from left to right.

The distance between the ii-th point and the (i+1)(i+1)-th point is aiai.

For each integer kk ranged from 11 to nn, you are asked to select exactly kk different given points on the line to maximize the sum of distances between all pairs of selected points.

Input

The input contains several test cases, and the first line contains a positive integer TT indicating the number of test cases which is up to 10001000.

For each test case, the first line contains an integer nn indicating the number of points, where 2≤n≤1052≤n≤105.

The second line contains (n−1)(n−1) positive integers a1,a2,⋯,an−1a1,a2,⋯,an−1, where 1≤ai≤1041≤ai≤104.

We guarantee that the sum of nn in all test cases is up to 106106.

Output

For each test case, output a line containing nn integers, the ii-th of which is the maximum sum of distances in case k=ik=i. You should output exactly one whitespace between every two adjacent numbers and avoid any trailing whitespace in this line.

Example

input

Copy

1
5
2 3 1 4

output

Copy

0 10 20 34 48

Note

The figure below describes the sample test case.

The only best selection for k=2k=2 should choose the leftmost and the rightmost points, while a possible best selection for k=3k=3 could contain any extra point in the middle.

题意:

给你n个点相邻点之间的距离

问你选(1~n)个点,使它们之间的距离和最大

输出(1~n)的情况

解析:

我们把n个区间,变成i个区间,答案等于,ans=(n-i)*(i)*a[i];

打表得:

自然是让中间的区间越大越好,所以选点是靠左选一个,再考右选一个,这样来回选,让中间的区间最大

每次加点,都要加一些边,加的边是原来的点到加的点的距离,我们可以用前缀和后缀以O(1)的复杂度来处理

注意ans会超int,注意前缀后缀数组要清0

ac:

#include<bits/stdc++.h>
#define ll long long
#define MAXN 100005
using namespace std;
ll a[MAXN];
ll b[MAXN];
ll suma[MAXN];
ll sumb[MAXN];
ll t,n;

ll get(ll aa,ll bb,ll x)//记录左边的点数,右边的点数,加点的位置
{
    ll ans=0;
    ans+=suma[aa]-aa*(b[n]-b[x]);
    ans+=sumb[bb]-(n-bb+1)*b[x];
    return ans;
}

int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(suma,0,sizeof(suma));
        memset(sumb,0,sizeof(sumb));
        scanf("%lld",&n);
        for(ll i=2;i<=n;i++)
            scanf("%lld",&a[i]);
        for(ll i=1;i<=n;i++)
            b[i]=b[i-1]+a[i];
        ll ssum=b[n];
        for(ll i=1;i<=n;i++)
        {
            ssum-=a[i];
            suma[i]=suma[i-1]+ssum;
        }
        ssum=b[n];
        for(ll i=n;i>=1;i--)
        {
            ssum-=a[i+1];
            sumb[i]=sumb[i+1]+ssum;
        }
        printf("0");
        printf(" %lld",b[n]);
        ll ans=b[n],tmp=0;
        ll aa=1,bb=n;
        for(ll i=3;i<=n;i++)
        {
            if(i%2==1)
            {
                tmp=get(aa,bb,aa+1);
                aa++;
            }
            else{
                tmp=get(aa,bb,bb-1);
                bb--;
            }
            ans+=tmp;
            printf(" %lld",ans);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41183791/article/details/89594943