2020-2021 gym/103185 D. Dividing Candy(siweim二进制)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020-2021 gym/103185 D. Dividing Candy(siweim二进制)相关的知识,希望对你有一定的参考价值。

LINK

考虑存在两个解满组条件

一组是 2 k 1 2^{k_1} 2k1 2 k 2 2^{k_2} 2k2

一组是 2 k 3 2^{k_3} 2k3 2 k 4 2^{k_4} 2k4

显然有 k 1 ! = k 3 & & k 1 ! = k 4 & & k 2 ! = k 3 & & k 2 ! = k 4 k_1!=k_3\\&\\&k_1!=k_4\\&\\&k_2!=k_3\\&\\&k_2!=k_4 k1!=k3&&k1!=k4&&k2!=k3&&k2!=k4

而又有 2 k 1 + 2 k 2 = 2 k 3 + 2 k 4 2^{k_1}+2^{k_2}=2^{k_3}+2^{k_4} 2k1+2k2=2k3+2k4

max ⁡ ( k 1 , k 2 ) ! = max ⁡ ( k 3 , k 4 ) \\max(k_1,k_2)!=\\max(k_3,k_4) max(k1,k2)!=max(k3,k4)

显然,存在有一遍的最大索引更大,那么这一组解的和会比另一组解更大,因为 2 k > 2 0 + 2 1 + 2 2 . . . + 2 k − 1 2^{k}>2^{0}+2^{1}+2^{2}...+2^{k-1} 2k>20+21+22...+2k1

所以解一定是唯一的,我们先特判掉 n = 1 n=1 n=1

然后不断模拟进位,看最后有几个位置上二进制数为 1 1 1,只要小于等于 2 2 2都是满足条件的

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int n,a[maxn],f[maxn];
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)	cin >> a[i];
	for(int i=1;i<=n;i++)	f[a[i]]++;
	int suf = 0;
	for(int i=0;i<=110000;i++)
	{
		f[i+1] += f[i]/2;
		if( f[i]&1 )	suf++;
	}
	if( n==1 )	cout << "N";
	else if( suf<=2 )	cout << "Y";
	else	cout << "N";
}

以上是关于2020-2021 gym/103185 D. Dividing Candy(siweim二进制)的主要内容,如果未能解决你的问题,请参考以下文章

数论思维D. X-Magic Pair

343D/Codeforces Round #200 (Div. 1) D. Water Tree dfs序+数据结构

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath

数论因数D. Not Adding

并查集最大连通块大小D. Social Network

cf1051 D. Bicolorings