随便 yy 的做法求 Hack
查看原帖
随便 yy 的做法求 Hack
224558
JackMerryYoung楼主2022/10/3 12:37

Rt:

感觉是先排序前后 NN 个数,然后考虑怎么删数最优。

可以删前 NN 个的最小值,让中间那一段的最左的那个数进入前面 NN 个。

也可以删后 NN 个的最大值,让中间那一段的最右的那个数进入后面 NN 个。

然后可以用堆维护最大最小,复杂度大概 O(Nlog2N)\mathcal{O}(N \log_2 N)?

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

#define ll long long
#define rint register ll

ll N;
ll prearr[300005];
ll midarr[300005];
ll sufarr[300005];

priority_queue< ll > suf;
priority_queue< ll, vector<ll>, greater<ll> > pre;

signed main()
{
    cin >> N;
    for(ll i = 1; i <= N; ++ i)
        cin >> prearr[i], pre.push(prearr[i]);

    for(ll i = 1; i <= N; ++ i)
        cin >> midarr[i];

    for(ll i = 1; i <= N; ++ i)
        cin >> sufarr[i], suf.push(sufarr[i]);

    ll head = 1, tail = N;
    while(head <= tail)
    {
        if(midarr[head] - pre.top() >= suf.top() - midarr[tail])
        {
            // cout << "Deleted " << pre.top() << endl;
            pre.pop();
            pre.push(midarr[head]);
            head ++;
        }
        else
        {
            // cout << "Deleted " << suf.top() << endl;
            suf.pop();
            suf.push(midarr[tail]);
            tail --;
        }
    }

    ll presum, sufsum;
    presum = sufsum = 0;
    while(!pre.empty())
    {
        presum += pre.top();
        pre.pop();
    }

    while(!suf.empty())
    {
        sufsum += suf.top();
        suf.pop();
    }

    cout << presum - sufsum << endl;
    return 0;
}
2022/10/3 12:37
加载中...