zoukankan      html  css  js  c++  java
  • 【】BZOJ3687: 简单题(dp+bitset)

    原文链接:https://www.cnblogs.com/zwfymqz/p/8696499.html

    题目描述

    Time Limit: 10 Sec Memory Limit: 512 MB
    Submit: 1138 Solved: 556
    [Submit][Status][Discuss]
    Description
    小呆开始研究集合论了,他提出了关于一个数集四个问题:
    1.子集的异或和的算术和。
    2.子集的异或和的异或和。
    3.子集的算术和的算术和。
    4.子集的算术和的异或和。
    目前为止,小呆已经解决了前三个问题,还剩下最后一个问题还没有解决,他决定把
    这个问题交给你,未来的集训队队员来实现。
    Input
    第一行,一个整数n。
    第二行,n个正整数,表示01,a2….,。
    Output
    一行,包含一个整数,表示所有子集和的异或和。
    Sample Input
    2
    1 3
    Sample Output
    6
    HINT

    【样例解释】

    6=1 异或 3 异或 (1+3)

    【数据规模与约定】

    ai >0,1<n<1000,∑ai≤2000000。

    另外,不保证集合中的数满足互异性,即有可能出现Ai= Aj且i不等于J

    题解:

    打死也想不出来系列QWQ…

    感觉自己的思维还是太僵化了,看到数列问题就开始想怎么优化枚举子集

    但是很显然这种子集问题是不可能通过枚举子集来实现的,

    正解:

    首先我们要把问题转化到值域上去考虑

    设f[i]表示子集和为i的方案,那么加入一个数x,所有的f[i]+=f[i−1]

    考虑到最后的异或操作,因此我们只维护方案的奇偶性即可

    这样的话用一个bitset就可以了

    bitset中的^,实际上就是%2

    #include<cstdio>
    #include<iostream>
    #include<bitset>
    #include<cstring>
    using namespace std;
    int N;
    bitset<2000001>bit;
    int main()
    {
        scanf("%d",&N);
        bit[0]=1;
        while(N--)
        {
            int x;
            scanf("%d",&x);
            bit^=bit<<x;
        }
        int ans=0;
        for(int i=2000000;i>=0;i--)
            if(bit[i]==1) 
                ans^=i;
        printf("%d",ans);
        return 0;
    }
    

    作者:自为风月马前卒
    个人博客http://attack204.com//
    出处:http://zwfymqz.cnblogs.com/

  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853135.html
Copyright © 2011-2022 走看看