[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();
}