H XOR
문제의 의미
독점의 모든 부분 집합을 충족하고자하는 숫자의 집합을 감안할 또는 0이며, 길이와
분석
n은 우리가 우리는 선형 그룹을 고려 일반적으로 XOR과 0의 세트 번호, 각 번호의 기여로 변환 찾을 확실히 가능한 부분 집합의 열거입니다, 1E5입니다,이 그룹 대수적으로 선형 그룹, 연구 그룹 세트 길이, 우리는 선형 대수학의 지식을 알 수 배열에 숫자를 소요, 선형베이스는 독점의 구성 또는 0있는 유일한 방법이있다. 각 그룹의 개수가 선형 아니다 이처럼, 수 자신의 서브 세트로 구성 될 수있다 \ (2 NR. (1)} ^ {\) 의 모든 수의 기여가 구성되도록 직선 그룹이 아닌 (\ (NR) * 2 {NR-1} ^ \) , 다음 선형 키리의 수에 대한 방법을 할까? , 어떤은, N-1은 다시 기본을 추구, 우리는 NR의 나머지 부분에 셀 수를 숫자를 나타내는 몇 가지 방법이 숫자를 표현할 수없는 남아 어떻게이 쇼의 번호로 변환 그것의 수는 단지 선형 정리에 의해 선형 그룹의 세트 같은 번호가 다를 수 있습니다 알고 있지만, 그들은 같은 순위하지만,이 숫자는 내부 선형 기본으로 표시 할 수 있도록 그는 몇 가지에 대한 우리의 나머지 또는 랭크 R 경우, 표현 될 수 있으며, 그 숫자가 구성되는 수 (N) 1-R-집합 기여 될 수 \ (2 NR. (1)} ^ {\) , 그렇지 않은 경우, 기여는 0
#include <cstdio>
#include <cmath>
#include <algorithm>
#include<vector>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef long long UI;
const int maxn=1e5+9;
int vis[maxn];
UI a[maxn];
const int mod=1e9+7;
ll mul(ll a,ll b){
return a%mod*b%mod;
}
ll fpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=mul(ans,a);
b>>=1;
a=mul(a,a);
}
return ans;
}
#define weishu 62
UI x[weishu+1];
struct LinearBasis{
UI basis[weishu+1];//32位
int num;
int cnt;//极大无关组大小
void clear(){ memset(basis,0,sizeof(basis)); num=0;cnt=0; }//清零
void insert(UI x){ basis[num++]=x; }//单纯存数组,没有插入线性基
bool d_insert(UI x){//直接插入线性基
bool flag=0;
for(int j=weishu;j>=0;j--)
if ((x>>j)&1) {
if (basis[j]==0) {
cnt++;
basis[j]=x;
return 1;
}
else {
x^=basis[j];
}
}
return 0;
}
void build(){//用数组里面存的数生成线性基
cnt=0;
num--;
for(int i=0;i<=num;i++) x[i]=basis[i];
memset(basis,0,sizeof(basis));
for(int i=0;i<=num;i++) {
for(int j=weishu;j>=0;j--)
if ((x[i]>>j)&1) {
if (basis[j]==0) {
cnt++;
basis[j]=x[i];
break;
}
else {
x[i]^=basis[j];
}
}
}
num=0;
}
int check(UI x){//判断一个数在不在线性基中
for(int i=weishu;i>=0;i--)
if ((x>>i)&1) {
if (basis[i]==0) break;
else x^=basis[i];
}
return (x==0);
}
}bs,bs2;
vector<int>v;
int main(){
int n;
while(scanf("%d",&n)==1){
v.clear();
bs.clear(),bs2.clear();
for(int i=1;i<=n;i++){
vis[i]=0;
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++){
if(bs.d_insert(a[i])){
v.push_back(i);
vis[i]=1;
}
}
ll r=bs.cnt;
ll ans=mul(n-bs.cnt,fpow(2,n-bs.cnt-1));
for(int i=1;i<=n;i++){
if(vis[i]==0){
bs2.d_insert(a[i]);
}
}
for(int i=0;i<v.size();i++){
bs=bs2;
for(int j=0;j<v.size();j++){
if(i!=j){
bs.d_insert(a[v[j]]);
}
}
if(bs.cnt==r)ans+=fpow(2,n-1-r);
}
ans%=mod;
printf("%lld\n",ans);
}
return 0;
}