题干:

链接:https://ac.nowcoder.com/acm/contest/881/H
来源:牛客网

Bobo has a set A of n integers a1,a2,…,ana1,a2,…,an.
He wants to know the sum of sizes for all subsets of A whose xor sum is zero modulo (109+7)(109+7).
Formally, find (∑S⊆A,⊕x∈Sx=0|S|)mod(109+7)(∑S⊆A,⊕x∈Sx=0|S|)mod(109+7). Note that ⊕⊕ denotes the exclusive-or (XOR).

输入描述:

The input consists of several test cases and is terminated by end-of-file.The first line of each test case contains an integer n.
The second line contains n integers a1,a2,…,ana1,a2,…,an.* 1≤n≤1051≤n≤105
* 0≤ai≤10180≤ai≤1018
* The number of test cases does not exceed 100.
* The sum of n does not exceed 2×1062×106.

输出描述:

For each test case, print an integer which denotes the result.

示例1

输入

复制

1
0
3
1 2 3
2
1000000000000000000 1000000000000000000

输出

复制

1
3
2

题目大意:

给你n个数字,然后让你求所有满足 异或和为0的子集 的大小之和。

解题报告:

根据期望的线性性(Orz),转化一下题意:相当于求每个数出现在子集中的次数之和。

那么如何求每个的合法出现次数呢?对于每个数x的出现次数,也就是这个数x必选的情况下,有多少种选择方案可以让剩余n-1个数凑出x来。然后就可以

先对n个数求线性基b1,设线性基大小为r,可以分别计算线性基内数的贡献和线性基外数的贡献

1.线性基外:共n-r个数,枚举每个数,让他必选,将线性基外剩余的个数任意排列(也可不选),则共有 种方案,每种方案再异或x的结果,能被刚刚求出的那组线性基唯一的异或出来,所以每个数的贡献为:。又因为一共有n-r个数,所以线性基外的数的贡献为:

2.线性基内:依旧是枚举每个数x(注意枚举的x是a数组中的数而不是b1中的数),求出剩余n-1个数凑出x的方案数,做法是这样的:将所有剩余的n-1个数再求一次线性基,设为b2,分两种情况:

(1) x不能被b2异或出。那么显然x不能在任意一个集合中出现,x的贡献为0。

(2) x可以被b2异或出。此时b2的大小必定也为r,因为b2已经能表示所有n个数了。那么在除去x和b2的情况下,剩余n-r-1个数显然也是任意排列,x贡献为 

对于在线性基内的方案统计时,还有另一种理解:因为这个数x在线性基内,也就是说他代表了二进制中的一个Bit位在线性基中的存在,那么我们要凑出这个x的话(注意x依旧是原数,而不是线性基内的数字),就必须要找一个可以代表这个Bit位的数字来替代他,也就是:用除去x的剩余n-1个数,重构一组线性基后,如果基的大小仍为b1.r,则说明x在原基b1中不是必须的,可以被替代,此时也才说明x对答案做出了贡献,不然的话只有x能代表这个Bit,那他代表给谁看?和谁去异或成0?所以对答案没有任何贡献。所以写代码最后一部分的时候,既可以这样写:if(b3.r == b1.r) 也可以这样写:if(b3.ins(a[i])==0)也就是说如果插不进去a[i]了,就代表他对答案做出了贡献,因为新基可以凑出所有数字。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
const ll mod = 1e9 + 7;
int n,top;
ll a[MAX],ans,tmp,b[MAX];
struct Node {ll Base[66];int r;void init() {memset(Base,0,sizeof Base);r=0;}bool ins(ll x) {for(int i = 62; i>=0; i--) {if(x & (1LL<<i)) {if(Base[i] == 0) {Base[i] = x;r++;return 1;}else x ^= Base[i];}if(x == 0) return 0;}return 0;}
} b1,b2,b3;
ll qpow(ll a,ll k) {ll res = 1;while(k) {if(k&1) {res = (res * a) % mod;}k>>=1;a = (a * a)%mod;}return res;
}
int main()
{while(~scanf("%d",&n)) {ans = tmp = 0;b1.init();b2.init();top=0;for(int i = 1; i<=n; i++) scanf("%lld",a+i);for(int i = 1; i<=n; i++) {if(b1.ins(a[i])) b[++top] = a[i];else b2.ins(a[i]);}if(n == b1.r) {printf("0\n");continue;}ans = (n-b1.r) * qpow(2,n - b1.r - 1);for(int i = 1; i<=top; i++) {b3 = b2;for(int j = 1; j<=top; j++) {if(i == j) continue;b3.ins(b[j]);}if(b3.r == b1.r) tmp++;}ans = ans + tmp*qpow(2,n - b1.r - 1);printf("%lld\n",ans%mod);}  return 0 ;
}

AC代码2:(咖啡鸡的代码,也不知道是维护了个啥)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+3;
const ll M=1000000007;
ll v;
struct base{ll r[64],o[64];bool ins(ll x){bool flag=0;ll tmp=0;for (int i=62;i>=0;i--)if (x>>i){if (!r[i]) o[i]=tmp|(1ll<<i),r[i]=x,flag=1;x^=r[i]; tmp^=o[i];if (!x) break;}if (!flag){v|=tmp;}return flag;}void clear(){for (int i=0;i<64;i++) r[i]=0,o[i]=0;}
}f;
ll pow_(ll x,ll y){ll ret=1;while (y){if (y&1) ret=ret*x%M;x=x*x%M; y>>=1;}return ret;
}
int n,w;
ll a[maxn],ans;int main(){while (scanf("%d",&n)==1){for (int i=1;i<=n;i++) scanf("%lld",&a[i]);for (int i=0;i<64;i++) v=0; f.clear(); ans=w=0;for (int i=1;i<=n;i++){ans+=!f.ins(a[i]);}for (int i=0;i<64;i++) {if (v&(1ll<<i)) ++ans;if (f.r[i]) ++w;}cout << ans*pow_(2ll,n-1-w)%M << endl;}return 0;
}

【2019牛客暑期多校训练营(第一场) - H】XOR(线性基,期望的线性性)相关推荐

  1. 2019牛客暑期多校训练营(第一场场)_I题Points Division(线段树+DP维护区间最大值)

    题目链接: https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点的坐标为(xi,yi),有两个权值ai,bi. 现在要你将它分成A,B两部分, ...

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

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

  3. 2019牛客暑期多校训练营(第三场)H.Magic Line

    2019牛客暑期多校训练营(第三场)H.Magic Line 题目链接 题目描述 There are always some problems that seem simple but is diff ...

  4. 2019牛客暑期多校训练营(第五场)C generator 2 (BSGS)

    2019牛客暑期多校训练营(第五场)C generator 2 思路 x0=x0x_0 = x_0x0​=x0​ x1=a∗x0∗bx_1 = a * x_0 * bx1​=a∗x0​∗b x2=a∗ ...

  5. 2019牛客暑期多校训练营(第四场)----E- triples II

    首先发出题目链接: 链接:https://ac.nowcoder.com/acm/contest/884/E 来源:牛客网 涉及:位运算,容斥定义,dp 点击这里回到2019牛客暑期多校训练营解题-目 ...

  6. 2019牛客暑期多校训练营(第一场)

    传送门 参考资料: [1]:官方题解(提取码:t050 ) [2]:标程(提取码:rvxr ) [3]:牛客题解汇总 A.Equivalent Prefixes(单调栈) •题意 定义两个数组 u,v ...

  7. 【2019牛客暑期多校训练营(第一场) - A】Equivalent Prefixes(单调栈,tricks)

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

  8. 2019牛客暑期多校训练营(第一场)E-ABBA(dp)

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

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

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

最新文章

  1. Linux登录那点事
  2. 安谋中国推出“山海” S12,AIoT 安全解决方案技术全解读
  3. C++ Primer 5th笔记(chap 16 模板和泛型编程)默认模板实参
  4. oracle的pdb,oracle pdb基本管理
  5. 5类6类7类网线对比_孩子们长高的黄金时期是从3月到5月,这阶段多吃6类食物长得快...
  6. 20行Python代码检测人脸是否佩戴口罩
  7. 贴一段Jenkins的自动发布脚本
  8. Linux下MySQL的简单使用(一)
  9. java三角函数计算器_java 计算器代码能实现三角函数和阶乘功能
  10. Jetpack—LiveData组件的缺陷以及应对策略 转至元数据结尾
  11. 【C++】图片转byte
  12. 多x多y的origin图_3本纯爱文推荐:医疗师 x 小狼狗,漫漫何其多经典
  13. linux cadaver 命令,screen命令用法与cadaver
  14. jsp_servlet【基础】
  15. 【转载】何时使用领域驱动设计
  16. 8 种实现垂直和水平居中元素的方法汇总
  17. 【花雕动手做】有趣好玩的音乐可视化系列小项目(18)--LED平面板灯
  18. VMware安装安卓模拟器
  19. cesium中加载点图标
  20. 无线网性能该如何测试

热门文章

  1. LINK : fatal error LNK1104: 无法打开文件“LIBCD.lib”
  2. 架构师之路(5)---IoC框架
  3. 如何将SAP数据传输到其他系统(Transferring Data from SAP to Other Systems)
  4. python用cmd运行失败_解决python在cmd运行时导入包失败,出现错误信息 ModuleNotFoundError: No module named ***...
  5. 子网掩码相关教学 子网掩码快速算法 沉睡不醒blog
  6. python工厂模式 理解_浅谈Python设计模式 - 抽象工厂模式
  7. 软件测试之黑盒测试-边界值分析法(理论白话学习/期中期末备考)
  8. ARM-Linux下交叉编译opessl-1.0.0
  9. asterisk1.8 拨号方案 mysql存储(动态)
  10. win7下ffmpeg编译动态链接库整理