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;
}

  

posted @ 2019-03-29 07:59  WstOne  阅读(110)  评论(0编辑  收藏  举报