题解 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

CF1361D Johnny and James(模拟)

CF-1362B. Johnny and His Hobbies

CF-1362B. Johnny and His Hobbies

CF-1362C. Johnny and Another Rating Drop

CF-1362C. Johnny and Another Rating Drop