Codeforces Round #751 (Div. 2) 的其他题解点我
C. Array Elimination
题目大意:
给出n个数,你可以任意次选择其中任意k个数进行操作,使这k个数减去其按位与(&)的和, 最终使n个数都为0,找出有多少个这样的k
思路:
手模下样例可以看出,
对于每一位,设1的个数为s,那么满足条件的k一定是s的因子,因为只有这样才能完美的消掉每一个1。
然后对于整个数,我们肯定要找出每一位都能满足条件的k,才能使整个数为0
AC代码:
#include <bits/stdc++.h>
#define PII pair<int,int>
#define ll long long
using namespace std;
const double eps = 1e-8;
const int maxn = 2e5 + 10;
const int mod = 1e9 + 7;
const int INF = 1<<30;
inline void swap(int &x, int &y){x^=y^=x^=y;}
inline int gcd(int a,int b) {return !b ? a : gcd(b,a%b);}
int a[maxn];
int ans[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
int n;
int tot = 0;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]), ans[i] = 0;//不要忘了初始化ans
for(int i = 0; i <= 30; ++i){//枚举所有位数
int cnt = 0;
for(int j = 1; j <= n; ++j){
if((1 << i) & a[j])cnt++;
}
if(cnt == 0){//如果是0的话所有数都可以
for(int j = 1; j <= n; ++j)ans[j]++;
}
else {//不为0的话其所有因子可以
for(int j = 1; j <= cnt; ++j)
if(cnt % j == 0)ans[j]++;
}
}
for(int i = 1; i <= n; ++i){//1是一定满足的,所以我们可以直接以1来判断
if(ans[i] == ans[1])printf("%d ", i);
}
printf("\n");
}
return 0;
}