说在前面
怕自己忘掉了…
赶紧写下来记录me的愚蠢
题目
题目大意
给出N个数字,N不超过50,数字大小不超过1048575
现在要将这个N个数字染上红色或者黑色,要求相同颜色的数字与起来的和相等,询问染色方案数
(注意:对于两个数A,B,A红B黑 和 A黑B红 是不同的染色方案)
输入输出格式
你需要写一个class,这个class大概长这样:
函数调用是允许的
class SetAndSet {
public :
long long countandset ( vector < int > A ) {
int n = A.size ( ) ;
long long ans = 0 ;
// here is your code
return ans ;
}
} ;
数组将会以vector传参的方式给出,函数返回值作为答案
解法
对每一个二进制位分开考虑
假设对于第k个二进制位:
如果所有数的第k位上全为0或全为1,那么显然无论怎么分组,两组的第k位都相等
如果不全为1,那么假设第k位上为0的数字集合为S。如果整个S都被染上了相同的颜色,显然第k位就不相等了。
那么可以考虑容斥,最终答案 = 总方案数 - 有一位不相等的 + 有两位不相等的….
在计算有多位不相等的时候,如果这两位对应的集合
S1,S2
S
1
,
S
2
有交集,那么
S1⋃S2
S
1
⋃
S
2
的所有元素颜色必须一致。如果没有交集,那么
S1
S
1
,
S2
S
2
的颜色只需要满足集合内部相同即可,而不需要保持颜色一致(me真是蠢到一种境界,写的时候直接钦定
S1
S
1
和
S2
S
2
颜色一致了,WA了两个小时才发现问题…)。
所以最终实现的时候,可以采用dfs+并查集维护连通块个数。
下面是自带大常数的代码
什么?代码?不存在的~