【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;
}
posted @ 2019-07-21 08:11  Dup4  阅读(463)  评论(0编辑  收藏  举报