https://ac.nowcoder.com/acm/contest/881/H


题意:

给定n个整数,求其中异或和为 \(0\) 的子集的大小的和。

题解思路:

首先转化为每个可以通过异或表示 \(0\) 的数贡献它参与的子集数。

思考的过程分两步。一开始不管三七二十一先对 \(n\) 个整数求一次线性基 \(B_1\) ,记其秩为 \(r\) 。

第一步:

先考虑线性基 \(B_1\) 外的数(假如有的话)产生的贡献。枚举每一个数,记这个数为 \(x\) ,除去这个数,线性基 \(B_1\) 外还有 \(n-r-1\) 个数,他们可以自由组合出 \(2^{n-r-1}\) 种子集,加上 \(x\) 本身之后,必定能被线性基 \(B_1\) 表示,故这些子集都会使得 \(x\) 发生贡献。这样的 \(x\) 共有 \(n-r\) 个。

第二步:

再考虑线性基 \(B_1\) 中的数产生的贡献。枚举每一个数,记这个数为 \(x\) ,这个数产生的贡献来源于他在第一步中被使用的次数。那怎么判断这个数被使用了多少次呢?把除去这个数 \(x\) 的 \(n-1\) 个数求出线性基 \(B_3\) 。假如 \(x\) 能被线性基 \(B_3\) 表示,此时 \(B_3\) 的秩必定为 \(r\) 。选中\(x\)之后,再从其他的 \(n-r-1\) 个数自由组合出子集,再从 \(B_3\)中选出对应的数配成 \(0\) 。否则这个 \(x\) 没有用。

第三步:

最后是快速得到 \(B_3\) 的办法,注意到 \(B_3\) 必定先通过除去 \(B_1\) 的 \(n-r\) 个数构造,可以把 \(n-r\) 先构造出 \(B_2\) ,然后再插入 \(B_1\) 内除x的 \(r-1\) 个数构成。

注意MN不能取64否则会爆掉ll。


qls说是hdu5544 http://acm.hdu.edu.cn/showproblem.php?pid=5544

题意:给定n个整数,求其中异或和为0的子集的大小的和。

题解思路:

首先转化为每个可以通过异或表示0的数贡献它参与的子集数。

对n个数进行一次消元,得到一组大小为\(r\)的线性基B1。

那么剩下的\(n-r\)个满足以下的规律:

设现在要计算的元素为X1,其他\(n-r-1\)个元素任意组合,总能得到一个整数,再加入X1也是一个整数,这个整数能被线性基B1表示,则这个X1可以对他们贡献总计\(2^{n-r-1}\)个次。

接下来算线性基B1里的数的贡献。

再对这\(n-r\)个数进行一次消元, 得到另一组线性基B2。枚举B1的一个线性基X2,对其他的r-1+B2个数消元,得到某个线性基B3。

csl:你必须钦定一个数必须选,如果这个数在线性基外面那没事,在里面你就得搞事情了。

意思是:这个数在线性基外面说明没有集合需要它的参与就可以自己组成异或和为0的。要是在线性基里面就说明存在这个数可以对某些集合产生贡献。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int MN=63;
const int mod=1000000007; ll num[100005]; struct LinearBase {
ll base[MN]; bool flag;//该线性基能否表示0
int cnt; void Copy(LinearBase b) {
cnt=b.cnt;
flag=b.flag;
memcpy(base,b.base,sizeof(base));
} void Clear() {
cnt=0;
flag=false;
memset(base,0,sizeof( base));
} //尝试向线性基中插入一个值
void Insert(ll x) {
for(int i=MN; ~i; i--)
if(x&(1ll<<i))
if(!base[i]) {
base[i]=x;
cnt++;
return;
} else
x^=base[i];
flag=true;
} //判断该线性基能否表示x
bool Check(ll x) {
for(int i=MN; ~i; i--)
if(x&(1ll<<i)) {
if(!base[i])
return false;
else
x^=base[i]; }
return true;
}
} B1,B2,B3; ll qpow(ll x,int n) {
ll res=1;
while(n) {
if(n&1)
res=res*x%mod;
x=x*x%mod;
n>>=1;
}
return res;
} ll ans,p2; vector<int>B1ID; int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out", "w", stdout);
#endif // Yinku
int n;
while(~scanf("%d", &n)) {
for(int i=1; i<=n; i++) {
scanf("%lld",&num[i]);
} B1.Clear();
B2.Clear();
B1ID.clear(); for(int i=1; i<=n; i++) {
if(B1.Check(num[i])) {
B2.Insert(num[i]);
} else {
B1.Insert(num[i]);
B1ID.push_back(i);
}
} ans=0;
if(n!=B1.cnt) {
p2=qpow(2,n-B1.cnt-1);
ans+=p2*(n-B1.cnt)%mod;
} for(ll i:B1ID) {
B3.Copy(B2);
for(ll j:B1ID) {
if(i!=j) {
B3.Insert(num[j]);
}
}
if(B3.Check(num[i])) {
//num[i]能被其他数表示
ans=(ans+p2)%mod;
}
} printf("%lld\n", ans);
}
}

2019牛客暑期多校训练营(第一场) - H - XOR - 线性基的更多相关文章

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  3. [题解] 2019牛客暑期多校第三场H题 Magic Line

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意:二维平面上有n个不同的点,构造一条直线把平面分成两个点数相同的部分. 题解:对这n个点以x为第一关键 ...

  4. 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)

    layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...

  5. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  6. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  7. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  8. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  9. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

随机推荐

  1. Windows 好用的护眼软件

    目录 1. 按 2. Windows10自带夜间模式 3. Iris Pro 3.1. 介绍 3.1.1. 保护用眼,改善睡眠 3.1.2. ×9 种不同的预设搭配 3.1.3. 计时器 3.1.4. ...

  2. Centos 7 环境下安装 RabbitMQ 3.6.10

    一.单机安装 在Centos7系统下部署(阿里云服务),使用yum安装 hostnamectl set-hostname rabbit01 #永久修改 1.1安装Erlang,因为RabbitMQ 是 ...

  3. MYSQL学习笔记——sql语句优化之索引

    上一篇博客讲了可以使用慢查询日志定位耗时sql,使用explain命令查看mysql的执行计划,以及使用profiling工具查看语句执行真正耗时的地方,当定位了耗时之后怎样优化呢?这篇博客会介绍my ...

  4. mycat权威指南阅读笔记--序言1

    前言 mycat官方地址http://www.mycat.io/,mycat是关系数据库的中间件,也就是说它可以把后端的多个数据库,抽象成一个关系数据库. mycat能干啥 官方文档介绍,主要是用来做 ...

  5. -bash: findstr: command not found 问题解决

    今天有个任务,需要获取apk的版本信息,百度之后说是之下下面的命令就行 adb shell dumpsys package com.baidu.searchbox | findstr versionC ...

  6. 【leetcode】1073. Adding Two Negabinary Numbers

    题目如下: Given two numbers arr1 and arr2 in base -2, return the result of adding them together. Each nu ...

  7. PHP实现跨服务器session共享的方法教程

    今天带来PHP实现跨服务器session共享的方法教程. 本文实例讲述了PHP实现cookie跨域session共享的方法.分享给大家供大家参考,具体如下: 做过web开发的小伙伴们都了解cookie ...

  8. bzoj1964: hull 三维凸包

    传送门 二维平面四个点求凸包面积->任选三个点面积之和/2 三维平面五个点求凸包体积->任选四个点体积之和/2 二维平面三个点面积->二个二维向量行列式值的绝对值/2 三维平面四个点 ...

  9. Linux C编程

    Linux C网络编程 1.Linux套接字 1.1 套接字介绍 套接字(Sockets),即为网络进程ID,是由运行这个进程的计算机的IP地址和这个进程使用的端口(Port)组成. 可以只用'net ...

  10. php面试专题---Mysql索引原理及SQL优化

    php面试专题---Mysql索引原理及SQL优化 一.总结 一句话总结: 注意:只写精品 1.为表设置索引要付出代价 是什么? 存储空间:一是增加了数据库的存储空间 修改插入变动索引时间:二是在插入 ...