[bzoj3687]简单题——bitset优化背包

题目链接

这道题可以说是学了 bitset b i t s e t 后做的第一题

但是还是 ylsoi y l s o i 手把手教我做的.. 我是真的菜…

首先这个题有个很坑的地方 它的数据是有问题的,读入每个数字的时候可能没有 n n 个,你只能边读边处理,存下来的话你会莫名WrongAnser的!!!

首先看这个问题,子集算术和想到了什么

背包问题不就计算了子集元素算术和吗

但是这个题直接跑背包发现复杂度太大了

但是这个题转移有个很妙的性质 因为要求的是答案的异或和

可以写出转移方程 f[x]=f[xa[i]] f [ x ] ⊕ = f [ x − a [ i ] ]

值域又不是很大 最后的结果只和答案的奇偶性有关

转移还用了位运算

我们不难想到用 bitset b i t s e t 来优化背包

每次转移的时候把 f f f<<a[i]异或一下就好了

复杂度 O(naω) O ( n ∑ a ω )

Codes
#include<bits/stdc++.h>

using namespace std;

const int N = 2e6 + 10;
bitset<N> f;
int a[N], n;

int main() {
#ifndef ONLINE_JUDGE
    freopen("3687.in", "r", stdin);
    freopen("3687.out", "w", stdout);
#endif
    scanf("%d", &n);
    int ans = 0; f[0] = 1;
    for(int i = 1, u; i <= n; ++ i) {
        scanf("%d", &u);
        f ^= (f << u);
    }
    for(int i = 0; i < N; ++ i)
        ans ^= f[i] * i;
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值