Description
Solution
原问题可以转化为求,最后再乘上一个
那么考虑容斥得到每一种集合的贡献,推一下容斥系数。
设表示集合大小为
时的容斥系数。
,此时相当于没有选任何操作,那么
中所有灯都是红色。
,此时如果被选了
的倍数次,那么最后容斥出来系数肯定应该是
,还要减去之前的容斥系数对这一次的影响,假设之前的集合大小为
,并且这些集合包含于大小于
的集合,这样的集合应该有
个。
设表示集合
的最小公倍数,那我们就可以把
用上述量表示出来了。
,发现这个式子本质上就是给予了每个集合一个权值,然后枚举每个集合,对其所有子集求权值和。这可以用
或者
,
算出。
总的时间复杂度。
Code_by_uselessName
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#define GET getchar()
#define LL long long
using namespace std;
namespace FastIO{
const LL L=(1<<20);
char buf[L],*S,*T;
#ifdef ONLINE_JUDGE
inline char getchar(){
if(S==T){T=(S=buf)+fread(buf,1,L,stdin);if(S==T)return EOF;}
return *S++;
}
#endif
inline LL read(){
LL s=0,f=1;char t=GET;
while('0'>t||t>'9'){if(t=='-')f=-1;t=GET;}
while('0'<=t&&t<='9'){s=(s<<1)+(s<<3)+t-'0';t=GET;}
return s*f;
}
}
using FastIO::read;
const LL N=25;
const LL Mod=998244353;
LL m,n,val[N],inv;
LL Fpow(LL a,LL b){
LL ans=1;
while(b){
if(b&1)ans=ans*a%Mod;
b>>=1;a=a*a%Mod;
}
return ans;
}
namespace Fast_Storm{
const LL _N=(1<<20);
LL gcd(LL a,LL b){
if(!b)return a;
return gcd(b,a%b);
}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL Lcm[_N],siz[_N],Sum[_N],C[N][N],P[N],Ans;
void Pre(LL up=20){
C[0][0]=1;
for(LL i=1;i<=up;i++){
C[i][0]=C[i][i]=1;
for(LL j=1;j<i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%Mod;
}
}
LL Upper(LL x){
return (x%Mod+Mod)%Mod;
}
void M(LL &x){
if(x>=Mod)x-=Mod;
if(x<0)x+=Mod;
}
void Fwt(LL Max){
for(LL i=1;i<Max;i<<=1)
for(LL j=0;j<Max;j+=(i<<1))
for(LL k=0;k<i;k++)M(Sum[i+j+k]+=Sum[j+k]);
}
void Solve(){
Pre();LL All=(1<<m)-1;
for(LL i=0;i<=m;i++){
P[i]=(i%4==0);
for(LL j=0;j<i;j++)M(P[i]-=C[i][j]*P[j]%Mod);
}
Lcm[0]=1;
for(LL S=0,pos;S<=All;S++){
if(S){
siz[S]=siz[S>>1]+(S&1);
for(LL i=1;i<=m;i++)if(S&(1<<i-1)){pos=i;break;}
Lcm[S]=min(lcm(Lcm[S^(1<<pos-1)],val[pos]),n+1);
}
M(Sum[S]=(P[siz[S]]*(n/Lcm[S]))%Mod);
}
Fwt(All+1);
for(LL S=0;S<=All;S++)M(Ans+=Sum[S]);
Ans=Ans*inv%Mod;
cout<<Ans<<'\n';
}
}
int main(){
n=read();m=read();
for(LL i=1;i<=m;i++)val[i]=read();
inv=Fpow(Fpow(2,m),Mod-2);
Fast_Storm::Solve();
return 0;
}