Codeforces Round 941 (Div. 2) F.Missing Subarray Sum

Missing Subarray Sum

题目描述

There is a hidden array a a a of n n n positive integers. You know that a a a is a palindrome, or in other words, for all 1 ≤ i ≤ n 1 \le i \le n 1in, a i = a n + 1 − i a_i = a_{n + 1 - i} ai=an+1i. You are given the sums of all but one of its distinct subarrays, in arbitrary order. The subarray whose sum is not given can be any of the n ( n + 1 ) 2 \frac{n(n+1)}{2} 2n(n+1) distinct subarrays of a a a.

Recover any possible palindrome a a a. The input is chosen such that there is always at least one array a a a that satisfies the conditions.

An array b b b is a subarray of a a a if b b b can be obtained from a a a by the deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.

输入描述

The first line of the input contains a single integer t t t ( 1 ≤ t ≤ 200 1 \le t \le 200 1t200) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer n n n ( 3 ≤ n ≤ 1000 3 \le n \le 1000 3n1000) — the size of the array a a a.

The next line of each test case contains n ( n + 1 ) 2 − 1 \frac{n(n+1)}{2} - 1 2n(n+1)1 integers s i s_i si ( 1 ≤ s i ≤ 1 0 9 1\leq s_i \leq 10^9 1si109) — all but one of the subarray sums of a a a.

It is guaranteed that the sum of n n n over all test cases does not exceed 1000 1000 1000.

Additional constraint on the input: There is always at least one valid solution.

输出描述

For each test case, print one line containing n n n positive integers a 1 , a 2 , ⋯ a n a_1, a_2, \cdots a_n a1,a2,an — any valid array a a a. Note that a a a must be a palindrome.

If there are multiple solutions, print any.

样例输入

7
3
1 2 3 4 1
4
18 2 11 9 7 11 7 2 9
4
5 10 5 16 3 3 13 8 8
4
8 10 4 6 4 20 14 14 6
5
1 2 3 4 5 4 3 2 1 1 2 3 2 1
5
1 1 2 2 2 3 3 3 3 4 5 5 6 8
3
500000000 1000000000 500000000 500000000 1000000000

样例输出

1 2 1 
7 2 2 7 
3 5 5 3 
6 4 4 6 
1 1 1 1 1 
2 1 2 1 2 
500000000 500000000 500000000

原题

Codeforces Round 941——传送门

题解

CF题解——传送门

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

vector<ll> create_arr(bool pry, vector<ll> v)
{
    deque<ll> dq;
    if (pry)
    {
        dq.push_back(v[0]);
    }
    else
    {
        dq.push_front(v[0] / 2);
        dq.push_back(v[0] / 2);
    }
    for (int i = 1; i < v.size(); i++)
    {
        dq.push_front((v[i] - v[i - 1]) / 2);
        dq.push_back((v[i] - v[i - 1]) / 2);
    }
    return vector<ll>(dq.begin(), dq.end());
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        int num = n * (n + 1) / 2 - 1;
        vector<ll> a(num);
        for (int i = 0; i < num; i++)
        {
            cin >> a[i];
            a[i] <<= 1;
        }
        sort(a.begin(), a.end());
        vector<ll> single;
        // 去重
        for (ll x : a)
        {
            if (!single.empty() && single.back() == x)
                single.pop_back();
            else
                single.push_back(x);
        }

        vector<ll> arr = create_arr(n & 1, single); // 构造出的数组

        vector<ll> sum(arr.size() + 1, 0); // 前缀和数组
        ll s = 0;                          // 数组总和
        for (int i = 1; i <= arr.size(); i++)
        {
            sum[i] = sum[i - 1] + arr[i - 1];
            s += arr[i - 1];
        }

        vector<ll> section_sum; // 区间和数组
        for (int i = 0; i < sum.size(); i++)
        {
            for (int j = i + 1; j < sum.size(); j++)
            {
                section_sum.push_back(sum[j] - sum[i]);
            }
        }
        sort(section_sum.begin(), section_sum.end());

        if (section_sum.size() <= a.size())
            swap(section_sum, a);
        int i;
        for (i = 0; a.rbegin()[i] == section_sum.rbegin()[i]; i++)
            ;
        ll x = 2 * section_sum.rbegin()[i] - s;
        if (single.size() > (n + 1) / 2)
            single.erase(find(single.begin(), single.end(), x));
        else
            single.insert(lower_bound(single.begin(), single.end(), x), x);
        vector<ll> ans = create_arr(n & 1, single);
        for (ll x : ans)
        {
            cout << x / 2 << ' ';
        }
        cout << '\n';
    }

    return 0;
}
  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值