• 【bzoj3687】简单题 背包dp+STL-bitset


    题目描述

    小呆开始研究集合论了,他提出了关于一个数集四个问题:
    1.子集的异或和的算术和。
    2.子集的异或和的异或和。
    3.子集的算术和的算术和。
    4.子集的算术和的异或和。
    目前为止,小呆已经解决了前三个问题,还剩下最后一个问题还没有解决,他决定把这个问题交给你,未来的集训队队员来实现。

    输入

    第一行,一个整数n。
    第二行,n个正整数,表示01,a2….,。

    输出

     一行,包含一个整数,表示所有子集和的异或和。

    样例输入

    2
    1 3

    样例输出

    6


    题解

    背包dp+STL-bitset

    首先想想暴力怎么做?设f[i]表示i出现在算术和中的次数,那么对于a[j],有f[i]+=f[i-a[j]]。最后统计哪些数出现了奇数次即可。

    那么怎么优化这个暴力?我们其实不需要知道某个数出现的具体次数,只需要知道它出现次数的奇偶性即可。

    所以我们可以使用bitset压位来解决。

    具体实现还是比较简单的,直接位运算然后异或即可。

    #include <cstdio>
    #include <bitset>
    using namespace std;
    bitset<2000010> f;
    int main()
    {
    	int n , i , x , m = 0 , ans = 0;
    	scanf("%d" , &n);
    	f[0] = 1;
    	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &x) , f ^= (f << x) , m += x;
    	for(i = 1 ; i <= m ; i ++ ) if(f[i]) ans ^= i;
    	printf("%d
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    log4j(七)——log4j.xml简单配置样例说明
    log4j(六)——log4j.properties简单配置样例说明
    三元运算符注意事项
    单精度浮点数操作
    反转链表算法Java实现
    VBS计时器2
    肖申克的救赎影评
    计算机中K到底是1000还是1024?
    二进制补码除法——计算机底层整数除法模拟之Java实现
    VBS计时器
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7000342.html
Copyright © 2020-2023  润新知