维护所有出现过的数构成的线性基,由于要输出方案,对于每个向量还要记一下它由哪些值异或而来。
用
bitset
b
i
t
s
e
t
,复杂度为
O(n332)
O
(
n
3
32
)
。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2100;
int k,n,m,sum;
bitset<N> b[N],a[N],cur,c;
int Ans[N];
ll s[N];
bool fl;
char nc() {
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int Read() {
int len=0;
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(;c>='0'&&c<='9';s[len++]=c-48,c=nc());
reverse(s,s+len);
return len;
}
void Get() {
m=Read();
c.reset();
int len=0;
ll t=1ll<<50;
while(m) {
ll cur=0;
for(int i=m-1;~i;i--) {
cur=cur*10+s[i];
s[i]=cur/t;cur%=t;
}
for(int i=0;i<50;i++) {
c[len++]=cur&1;cur>>=1;
}
while(m&&!s[m-1]) --m;
}
}
int main() {
scanf("%d",&n);
for(int i=0;i<n;i++) {
Get();fl=0;
cur.reset();cur[i]=1;
for(int j=N-1;~j;j--)
if(c[j]) {
if(a[j].any()) {
c^=a[j];cur^=b[j];
if(!c.any()) {
int tot=0;fl=1;
for(int k=0;k<i;k++) if(cur[k]) Ans[++tot]=k;
printf("%d",tot);
for(int k=1;k<=tot;k++) printf(" %d",Ans[k]);
putchar('\n');
break;
}
} else {
b[j]=cur;a[j]=c;
break;
}
}
if(!fl) puts("0");
}
return 0;
}