题解 CF1361B Johnny and Grandmaster
Posted BreezeEnder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 CF1361B Johnny and Grandmaster相关的知识,希望对你有一定的参考价值。
目前(洛谷)最优解写法。
首先将 \\(k_i\\) 降序排列,并将相同的 \\(k_i\\) 合并。由于每个式子都是形如 \\(p^k_i\\) 的形式,即底数相同,可以考虑变成 \\(p\\) 进制,发现对于任意 \\(c_1,\\, \\ldots ,\\, c_i+1\\) 和 \\(a_0 < a_1 < a_2 \\ldots < a_i+1\\),满足 \\(c_i+1 \\times p^a_i+1 \\ge \\sum\\limits_j=1^i c_j \\times p_a_j\\) 时,\\(c_i+1 \\times p^a_i+1 - \\sum\\limits_j=1^i c_j \\times p_a_j\\) 一定被 \\(p^a_0\\) 整除。
我们可以考虑记录 \\(s1,\\,s2\\) 表示两堆的和,使任意时刻 \\(s1 < s2\\)。
考虑 \\(k_i\\) 降序排序时贪心用较大的 \\(k\\) 补足 \\(s2-s1\\)。\\(\\textnow\\) 当前到 \\(i\\),且 \\(p^k_i \\times \\textnow = s2 - s1\\)。由于是降序排序,如果 \\(\\textnow > n\\) 那么后面的 \\(k\\) 都一定分配到 \\(s1\\)。否则先使 \\(s1=s2\\),再用剩下的 \\(k_i\\) 分配给 \\(s1,s2\\),注意满足 \\(s1<s2\\)。
\\(\\textCode\\):
def(N, int, 1e6 + 5)
def(p, int, 1e9 + 7)
int n, m;
int k[N];
int main()
int t; qread(t);
W(t)
qread(n, m);
rep(i, 1, n) qread(k[i]);
sort(k + 1, k + n + 1, greater<int>());
ll nw = 0;
ll s1 = 0, s2 = 0;
rep(i, 1, n)
if(nw && m != 1 && i != 1)
int nwm = k[i - 1] - k[i];
rep(j, 1, nwm)
nw *= m;
if(nw > n)
rep(l, i, n) s1 = (s1 + qpow(k[l], m, p)) % p;
goto End;
int cn = 0, j = i;
while(j <= n && k[i] == k[j]) ++j, ++cn;
int ps = min(nw, (ll)cn); nw -= ps;
if(cn > ps)
cn -= ps;
int c1 = cn >> 1, c2 = cn - c1;
if(c1 != c2) nw = 1;
s1 = qpow(k[i], m, p) * c1 % p;
s2 = qpow(k[i], m, p) * c2 % p;
else s1 = (s1 + qpow(k[i], m, p) * cn % p) % p;
i = j - 1;
// cout << s1 << \' \' << s2 << endl;
End:;
printf("%lld\\n", (s2 - s1 + p) % p);
return 0;
以上是关于题解 CF1361B Johnny and Grandmaster的主要内容,如果未能解决你的问题,请参考以下文章
CF-1362D. Johnny and Contribution
CF-1362B. Johnny and His Hobbies
CF-1362B. Johnny and His Hobbies