【ABC 134】D - Preparing Boxes
题意:
有\(n\)盒子,每个盒子内可以放\(1\)个球或者不放球,问能否由一种放置方案,使得标号为\(i\)的倍数的所有盒子的小球数量模\(2\)等于\(a_i\)。
思路:
显然我们可以倒着放,因为倒着放,在我处理当前盒子的时候不会影响右边,只会影响左边。
那么我们计算一下右边对当前盒子标号的贡献,如果是对的,就不放,否则就放一个。
时间复杂度:\(\mathcal{O}(n log n)\)
代码:
#include <bits/stdc++.h>
using namespace std;
#define N 200010
int n, a[N], b[N];
bool ok() {
for (int i = 1; i <= n; ++i) {
int tot = 0;
for (int j = i; j <= n; j += i) {
tot = tot + b[j];
tot %= 2;
}
if (tot ^ a[i]) return 0;
}
return 1;
}
int main() {
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++i) scanf("%d", a + i);
for (int i = n; i >= 1; --i) {
int now = 0;
for (int j = i + i; j <= n; j += i) {
now += b[j];
now %= 2;
}
b[i] = now ^ a[i];
}
if (ok()) {
vector <int> vec;
for (int i = 1; i <= n; ++i) if (b[i]) vec.push_back(i);
int sze = (int)vec.size();
printf("%d\n", sze);
for (int i = 0; i < sze; ++i) printf("%d%c", vec[i], " \n"[i == sze - 1]);
} else puts("-1");
}
return 0;
}