[CF1362E] Johnny and Grandmaster - 贪心

Description

把一组数分成两个集合,使这两个集合的对p的次方的和的差的最小值。

Solution

我们每挑出一个数,就往后挑一段使得这个数和这一段的和是相等的,如果找不到这一段,则这个数和剩下的后缀和的差就是答案

为了防止被卡,判断差为 0 时不能只用 \(10^9 + 7\),还需要再搞一个辅助模数

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

#define int long long

const int mod = 1e9 + 7;
const int mmm = 1e9 + 3;

int qpow(int p, int q, int mod)
{
    return (q & 1 ? p : 1) * (q ? qpow(p * p % mod, q / 2, mod) : 1) % mod;
}

void solve()
{
    int n, p;
    cin >> n >> p;
    int chk = 0, ans = 0;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a.begin(), a.end());
    reverse(a.begin(), a.end());
    for (int i = 0; i < n; i++)
    {
        if (ans || chk)
        {
            ans = (ans + mod - qpow(p, a[i], mod)) % mod;
            chk = (chk + mmm - qpow(p, a[i], mmm)) % mmm;
        }
        else
        {
            ans = (ans + qpow(p, a[i], mod)) % mod;
            chk = (chk + qpow(p, a[i], mmm)) % mmm;
        }
    }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);

    int t;
    cin >> t;

    while (t--)
        solve();
}

相关文章: