0
点赞
收藏
分享

微信扫一扫

Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)

凌得涂 2022-07-12 阅读 63

​​传送门​​

  • Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define
  • 考虑令线性基Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_02 的大小为 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_03,能表示的数为 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_04
    对于简单版本,若 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_05 可以暴力 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_06,否则考虑为 0 的 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_07 位,若之前选了某些数,那么对这些为 0 的位有一些贡献,选为 1 的位贡献一定为 1,那么我们把这 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_07 位压下来,Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_09 表示到第 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_10 位,选了 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_11 个,集合为 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_12 的方案数即可
  • Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_13:考虑求第 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_14 位的答案,令 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_15 那么最后的答案就是 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_16,这个写成 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_17 的形式就是 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_18,这个的意义就是
    Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_19,下面来探究这两个的性质
  • 首先Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_20 的值只与 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_21 有关,强行推导一波
    Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_22
    现在需要知道 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_23
    注意到 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_02 的性质,首先线性基中的运算是封闭的
    Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_25,所以 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_26, 即 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_27
    又注意到 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_28 当且仅当 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_12Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_04 中任意一个数交为偶数(考虑 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_17 的意义)
    这个等价于与任何一个基交为偶数,而且个数恰为 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_线性基_32(不会证,可以构造)
    强行构造一下,就是为 0 位的列向量转置后当前位添加一个 1,交只可能是 0 或是 2
    这个 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_07 个任意线性组合均可(Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_i++_34
    那么暴力构造出来 Codeforces Round 635 Div1 E2(线性基)(FWT)(组合数学)_#define_06,然后处理一下系数即可
#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;
}


举报

相关推荐

0 条评论