-
-
考慮令線性基 的大小爲 ,能表示的數爲
對於簡單版本,若 可以暴力 ,否則考慮爲 0 的 位,若之前選了某些數,那麼對這些爲 0 的位有一些貢獻,選爲 1 的位貢獻一定爲 1,那麼我們把這 位壓下來, 表示到第 位,選了 個,集合爲 的方案數即可 -
:考慮求第 位的答案,令 那麼最後的答案就是 ,這個寫成 的形式就是 ,這個的意義就是
,下面來探究這兩個的性質 -
首先 的值只與 有關,強行推導一波
現在需要知道
注意到 的性質,首先線性基中的運算是封閉的
,所以 , 即
又注意到 當且僅當 與 中任意一個數交爲偶數(考慮 的意義)
這個等價於與任何一個基交爲偶數,而且個數恰爲 (不會證,可以構造)
強行構造一下,就是爲 0 位的列向量轉置後當前位添加一個 1,交只可能是 0 或是 2
這個 個任意線性組合均可()
那麼暴力構造出來 ,然後處理一下係數即可
#include<bits/stdc++.h>
#define cs const
#define pb push_back
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(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
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;
}