传送门
- 考虑令线性基
的大小为
,能表示的数为
对于简单版本,若可以暴力
,否则考虑为 0 的
位,若之前选了某些数,那么对这些为 0 的位有一些贡献,选为 1 的位贡献一定为 1,那么我们把这
位压下来,
表示到第
位,选了
个,集合为
的方案数即可
:考虑求第
位的答案,令
那么最后的答案就是
,这个写成
的形式就是
,这个的意义就是
,下面来探究这两个的性质
- 首先
的值只与
有关,强行推导一波
现在需要知道
注意到的性质,首先线性基中的运算是封闭的
,所以
, 即
又注意到当且仅当
与
中任意一个数交为偶数(考虑
的意义)
这个等价于与任何一个基交为偶数,而且个数恰为(不会证,可以构造)
强行构造一下,就是为 0 位的列向量转置后当前位添加一个 1,交只可能是 0 或是 2
这个个任意线性组合均可(
)
那么暴力构造出来,然后处理一下系数即可
using namespace std;
cs int Mod = 998244353, iv2=(Mod+1)>>1;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a,b); }
void Dec(int &a, int b){ a = dec(a,b); }
void Mul(int &a, int b){ a = mul(a,b); }
int ksm(int a, int b){ int as=1; for(;b;b>>=1,a=mul(a,a)) if(b&1) as=mul(as,a); return as; }
typedef long long ll;
cs int N = 2e5 + 50;
cs int M = 60;
cs int K = 1 << 18;
int n, m, bin[K]; ll a[M];
vector<ll> b; int as[M];
void ins(ll x){
for(int i=m-1;~i;i--)
if(x>>i&1){ if(a[i]) x^=a[i]; else{ a[i]=x; b.pb(i); return; } }
}
int clc(ll x){
int as=bin[x&(K-1)]; x>>=18;
as+=bin[x&(K-1)]; x>>=18; as+=bin[x]; return as;
}
void dfs(int u, ll now){
if(u==(int)b.size()){ ++as[clc(now)]; return; }
dfs(u+1,now^a[b[u]]); dfs(u+1,now);
}
void work_Small(){ dfs(0,0); for(int i=0,coe=ksm(2,n-b.size()); i<=m; i++) cout<<mul(coe,as[i])<<" "; }
vector<ll> S; int ct[M];
void Dfs(int u, ll now){
if(u==(int)S.size()){ ++ct[clc(now)]; return; }
Dfs(u+1,now^S[u]); Dfs(u+1,now);
}
void work_Large(){
static int C[M][M];
for(int i=0; i<=m; i++) C[i][0]=1;
for(int i=1; i<=m; i++) for(int j=1; j<=i; j++)
C[i][j]=add(C[i-1][j-1],C[i-1][j]);
for(int i=m-1;~i;i--) if(a[i])
for(int j=i+1; j<m; j++) if(a[j]>>i&1) a[j]^=a[i];
for(int i=0; i<m; i++) if(!a[i]){ ll T=0;
a[i]=1ll<<i;
for(int j=0; j<m; j++) T=(T<<1)+(a[j]>>i&1); S.pb(T);
} Dfs(0,0); int iv=ksm(iv2,m);
for(int i=0,mt=mul(iv,ksm(2,n)); i<=m; i++){
int as=0; for(int k=0; k<=m; k++){
int coef=0; for(int j=0,coe,u=min(k,i); j<=u; j++)
coe=mul(C[k][j],C[m-k][i-j]),(j&1)?Dec(coef,coe):Add(coef,coe);
Add(as,mul(coef,ct[k]));
} cout<<mul(as,mt)<<" ";
}
}
int main(){
freopen("1.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=0; i<(1<<18); i++) bin[i]=bin[i>>1]+(i&1);
for(int i=1; i<=n; i++){
ll x; scanf("%lld",&x); ins(x);
} if(b.size()<=26) work_Small();
else work_Large(); return 0;
}