QOJ 6344 The Best Problem of 2021
xiaoyaowudi · · 个人记录
题目描述
给定
题解
以下第
定义
首先将
对于一个
由于主元列只有一个
那么,设
其中
那么,求出
因为,对于
同理,这里只需找到
从
-
当前已经确定了
a_{l-j+1},a_{l-j+2},\dots a_l ,a_1,a_2,\dots a_{l-j} 都还未确定。\mathrm{Hi}\left(a_1\right)>\mathrm{Hi}\left(a_2\right)\cdots >\mathrm{Hi}\left(a_{l-j}\right)\ge i> \mathrm{Hi}\left(a_{l-j+1}\right)>\cdots >\mathrm{Hi}\left(a_l\right) -
-
对于所有满足以上两个条件的
\left\{a_{l-j+1},a_{l-j+2},\cdots a_l\right\} ,以及a_{1},a_{2},\cdots a_{l-j} 的后i 位,令\displaystyle\left\{T\bigoplus_{i\in S}a_{i}\mid \forall S\subseteq \left(l-j,l\right]\cap Z\right\}\bigcap \left\{\le Y\right\}=t ,2^t 之和。
初始值
考虑
令
第一种情况:第
(1)
(2)
第二种情况:第
对于每种
(1)
(2)
(3)
(4)
需要额外分类讨论一下
由于
知道
总复杂度
Code
#include <iostream>
#include <algorithm>
#include <bitset>
constexpr int N(2010),p(998244353);
std::bitset<N> b[N];bool hv[N];
int fp(int a,int b){int ans(1),off(a);while(b){if(b&1) ans=1ll*ans*off%p;off=1ll*off*off%p;b>>=1;}return ans;}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n,m;
std::cin>>n>>m;
static std::bitset<N> a[N],xb;
for(int i(1);i<=n;++i)
{
static char s[N];std::cin>>s;
for(int j(0);j<m;++j)
{
a[i][m-j-1]=(s[j]=='1');
}
bool st(false);
for(int j(m-1);j>=0;--j) if(a[i][j])
{
if(hv[j])
{
a[i]^=b[j];
}
else
{
hv[j]=st=true;
b[j]=a[i];
break;
}
}
if(!st){std::cout<<0<<std::endl;return 0;}
}
{
static char s[N];std::cin>>s;
for(int j(0);j<m;++j) xb[m-j-1]=(s[j]=='1');
}
for(int i(m-1);i>=0;--i) if(hv[i]) for(int j(i+1);j<m;++j) if(hv[j] && b[j][i]) b[j]^=b[i];
static int x[N];int cnt(0);
static std::bitset<N> cur;
for(int j(m-1);j>=0;--j) if(hv[j])
{
std::bitset<N> nw(cur^b[j]);
bool cap(true);
for(int t(m-1);t>=0;--t) if(xb[t]!=nw[t])
{
if(xb[t]<nw[t]) cap=false;
break;
}
if(cap) cur=nw,x[++cnt]=1;
else x[++cnt]=0;
}
if(!x[1]){std::cout<<0<<std::endl;return 0;}
static int p2[N],pp2[N],ip2[N],ipr[N][N],inv[N];p2[0]=1;pp2[0]=2;ip2[0]=1;
constexpr int inv2((p+1)/2);
static int f[N][N],g[N][N];
for(int i(1);i<N;++i) p2[i]=2ll*p2[i-1]%p,pp2[i]=1ll*pp2[i-1]*pp2[i-1]%p,ip2[i]=1ll*ip2[i-1]*inv2%p;
inv[1]=1;for(int i(2);i<N;++i) inv[i]=1ll*(p-p/i)*inv[p%i]%p;
for(int i(0);i<=n;++i){ipr[i][0]=1;for(int j(1);j<=n;++j) ipr[i][j]=1ll*ipr[i][j-1]*ip2[i]%p;}
static int qf[N],iqf[N];
qf[0]=iqf[0]=1;for(int i(1);i<N;++i) qf[i]=1ll*qf[i-1]*(p2[i]-1)%p,iqf[i]=fp(qf[i],p-2);
auto qb=[](int a,int b)->int{return 1ll*qf[a]*iqf[b]%p*iqf[a-b]%p;};
f[0][0]=2;
for(int i(1);i<n;++i)
{
int c(x[n-i+1]);
for(int j(0);j<=i;++j)
{
unsigned long long cur(0);
if(c==0)
{
cur+=1ll*ipr[i-j][j]*inv2%p*qb(i-1,j);
cur+=1ll*ip2[j+1]*f[i-1][j];
if(j) cur+=f[i-1][j-1];
}
else
{
cur+=1ll*pp2[j]*ipr[i-j][j]%p*inv2%p*qb(i-1,j);
cur+=1ll*ip2[j+1]*f[i-1][j];
if(j) cur+=1ll*f[i-1][j-1]*pp2[j-1];
}
f[i][j]=cur%p;
}
}
static int sum[N];
sum[0]=1;
for(int j(1);j<=n;++j)
{
sum[j]=(1ll*f[n-1][j-1]*pp2[j-1]%p*fp(2,(n-j)*j)+1ll*pp2[j]*qb(n-1,j))%p*inv2%p;
}
for(int j(0);j<=cnt;++j)
{
for(int k(0);k<j;++k)
{
sum[j]=(sum[j]+1ll*(p-sum[k])*qb(cnt-k,j-k))%p;
}
}
std::cout<<sum[n]<<std::endl;
return 0;
}