题目链接:https://ac.nowcoder.com/acm/contest/1109/C
注意线性基的交不能简单的查询是否相关,并是可以直接并的,大部分人采用的是直接容斥的做法,其实是有基的交的算法的,贴在下面。标程好像是用的高斯消元求秩(然而蒟蒻不会)。
struct L_B{
ll base[maxbit];
void clear(){
memset(base,0,sizeof(base));
}
void ins(ll number){
for(int j = maxbit-1; j >= 0; j--) if(number>>j) {
if(!base[j]){
base[j] = number;
return;
}
else{
number ^= base[j];
}
}
return;
}
void intersect(L_B A, L_B B){
L_B C=B,D=B;
for(int i = 0; i < maxbit; i++){
ll x = A.base[i];
if(!x) continue;
int j = i;ll T = 0;
for(; j >= 0; j--) if(x>>j) {
if(C.base[j]){
x ^= C.base[j];
T ^= D.base[j];
} else break;
}
if(!x) base[i] = T;
else {
C.base[j] = x;
D.base[j] = T;
}
}
}
bool check(ll number){
for(int i = maxbit-1; i >= 0; i--) if(number>>i) {
if(!base[i]) return false;
number ^= base[i];
}
return true;
}
};
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 105
#define maxm 1006
#define ll long long int
#define INF 0x3f3f3f3f
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
#define mem(a) memset(a,0,sizeof(a))
#define sqr(x) (x*x)
#define inf (ll)2e18+1
#define PI acos(-1)
#define mod 1000000007
#define auto(i,x) for(int i=head[x];i;i=ed[i].nxt)
ll read(){
ll x=0,f=1ll;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
int n,B=61;
ll a[100],b[100],c[maxn],d[maxn];
void insert(ll P[],ll x) {
for(int i = B; i >= 0; i--) {
if((1ll<<i)&x) {
if(!P[i]) {P[i] = x; break;}
x ^= P[i];
}
}
}
int Query(ll P[],ll x) {
for(int i = B; i >= 0; i--) {
if((x >> i) & 1) {
if(!P[i]) return 0;
x ^= P[i];
}
}
if(x == 0) return 1;
else return 0;
}
int main()
{
//printf("%lld\n",(1ll<<B));
while(~scanf("%d",&n)){
ll x;
inc(i,1,n)c[i]=read();
sort(c+1,c+n+1);
int len1=unique(c+1,c+n+1)-c-1;
inc(i,1,len1)insert(a,c[i]);
int cnt=0;
ll ans=0;
inc(i,0,60)if(a[i])cnt++;
ans+=1ll<<cnt;
cnt=0;
inc(i,1,n)d[i]=read();
sort(d+1,d+n+1);
int len2=unique(d+1,d+n+1)-d-1;
inc(i,1,len2)insert(b,d[i]);
inc(i,0,60)if(b[i])cnt++;
ans+=1ll<<cnt;
cnt=0;
inc(i,0,60)if(b[i])insert(a,b[i]);
inc(i,0,60)if(a[i])cnt++;
ans-=1ll<<cnt;
mem(a);mem(b);cnt=0;
printf("%lld\n",ans);
}
return 0;
}