链接:https://ac.nowcoder.com/acm/contest/881/H
来源:牛客网
题目描述
Bobo has a set A of n integersa1,a2,…,an.
He wants to know the sum of sizes for all subsets of A whose xor sum is zero modulo (10^9+7)
Formally, find (∑S⊆A,⊕x∈Sx=0|S|)mod(10^9+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≤10^5 * 0≤ai≤10^18 * The number of test cases does not exceed 100. * The sum of n does not exceed 2×10^6.
输出描述:
For each test case, print an integer which denotes the result.
输入
1 0 3 1 2 3 2 1000000000000000000 1000000000000000000
输出
1 3 2
题解:
给你n个数字的集合,求满足下面这个条件的所有子集合的长度之和:
子集合满足:所有元素异或为0.。 集合的长度为元素个数
参考某大佬的博客,写的很容易理解:https://blog.csdn.net/u013534123/article/details/96482572
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=63;
const int maxn=1e5+5;
const int mod=1e9+7;
ll x[maxn],tot; //存储不是线性基内的n-r个数
ll a[N+1],b[N+1],c[N+1],cnt[N+1],cnt2[N+1],r;
ll n;
ll ksm(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
bool calc(ll *a,ll s){
for(int j=N;j>=0;j--){
if(s>>j&1){
if(a[j]==0){
a[j]=s;
break;
}else{
s^=a[j];
}
}
}
return s==0;
}
int main(){
while(scanf("%d",&n)!=EOF){
r=tot=0;
for(int i=0;i<=N;i++) a[i]=b[i]=c[i]=0;
for(int i=1;i<=n;i++){
ll s;
scanf("%lld",&s);
if(!calc(a,s)){
cnt[r++]=s;
}else{
x[tot++]=s;
}
}
if(n==r){
printf("0\n");
continue;
}
ll m=ksm(2,n-r-1);
ll ans=(n-r)*m%mod;
for(int i=0;i<tot;i++){
calc(b,x[i]);
}
for(int i=0;i<r;i++){
memcpy(c,b,sizeof b);
memcpy(cnt2,cnt,sizeof cnt);
for(int k=0;k<r;k++){
if(k==i) continue;
calc(c,cnt2[k]);
}
int num=0;
for(int j=0;j<=N;j++) if(c[j]) num++;
if(num==r) ans=(ans+m)%mod;
}
printf("%lld\n",ans);
}
return 0;
}