HDU-1709 The Balance(生成函数)
题意
给$n$个数,有哪些属于$1$到$n$个数字总和$sum$的数是通过该集合任意子集之间的加减运算无法得到的。
思路
对每个数构造$x^{-a[i]}+1+x^{a[i]}$,为了避免负幂次可以将整个下标记右移$sum$,处理幂次之间的加减关系时注意细节。
代码
#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl;
using namespace std;
const int N = 300000 + 5;
int n, a[N], ans[N], c[2][N];
int main() {
while(~scanf("%d", &n)) {
memset(c, 0, sizeof c);
int sum = 0, tot = 0;
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), sum += a[i];
int mid = sum + 1, maxs = mid + sum;
c[1][mid - a[1]] = c[1][mid] = c[1][mid + a[1]] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= maxs; j++) {
for(int k = mid - a[i]; k <= mid + a[i]; k += a[i]) {
int det = k - mid + j - mid;
if(mid + det < 0) continue;
c[i & 1][mid + det] += c[1 - (i & 1)][j];
}
c[1 - (i & 1)][j] = 0;
}
}
for(int i = mid + 1; i <= mid + sum - 1; i++) if(!c[n & 1][i]) ans[++tot] = i - mid;
printf("%d\n", tot);
for(int i = 1; i <= tot; i++) {
if(i != tot) printf("%d ", ans[i]);
else printf("%d\n", ans[i]);
}
}
return 0;
}