题解:AT_agc026_f [AGC026F] Manju Game

· · 题解

没有独立切的妙妙题!感觉是普及组,但是它的位置不太普及(符合 AGC 刻板印象(?

下文中,先 / 后手指人,先 / 后行指具体的先后次序。我的 \sout{\LaTeX} 水平显著提高(

自然地,把奇数位和偶数位上的数分开,分别记作 o, e。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

// #define Debug
// #define LOCAL
// #define TestCases

constexpr int N = 3e5;

int n;
int a[N + 5];

int Odd, Even;
int s[N + 5];

bool check(int delta)
{
    int Min = 0;
    for (int i = 1; i <= n; i += 2)
    {
        if (s[i] - Min >= delta)//dp[i] = true
            Min = min(Min, s[i + 1]);//dp[i] <- dp[j], sum(i, j + 2) >= delta -> s[i] - s[j + 1] >= delta
    }
    return s[n] - Min >= delta;//dp[n]
}

void solve()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];

        if (i & 1)
            Odd += a[i], s[i] = s[i - 1] + a[i];
        else
            Even += a[i], s[i] = s[i - 1] - a[i];
    }

    if (!(n & 1))//even
    {
        cout << max(Odd, Even) << " " << min(Odd, Even) << '\n';
        return ;
    }

    int l = 0, r = Odd + Even, delta = 0;
    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if (check(mid))
        {
            delta = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }

    cout << Even + delta << " " << Odd - delta << '\n';
    return ;
}

int main()
{
    #ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("mycode.out", "w", stdout);
    #endif

    ios :: sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);

    int T = 1;

    #ifdef TestCases
    cin >> T;
    #endif

    while (T--)
        solve();
    return 0;
}