LOJ#6358. 前夕
Description
为了抵御以尼古拉奥尔丁为首的上古龙族的入侵,地球的守护者 Yopilla 集齐了$n$种人类文明的本源力量 —— 世界之力。
Yopilla 打算使用若干种技能来对抗尼古拉奥尔丁的进攻。每种技能由若干种世界之力构成。换句话说,一共有$2^n$种技能,Yopilla 要使用若干种技能来对抗尼古拉奥尔丁。
大战前夕,Yopilla 走在波士顿的街头,突然看见天空中飞过了$4$只白鸽,他便洞察了战胜尼古拉奥尔丁的秘密:只要他使用的技能中,都含有的世界之力的种类数恰好为$4$的倍数,他便可以打败敌人。
Yopilla 想知道,他有多少种使用技能的情况,能战胜敌人。请你替 Yopilla 回答这个问题,答案对$998244353$取模即可。
Solution
设$f(k)$表示交集中至少有$k$个元素的方案数,$g(k)$表示交集恰好有$k$个元素的方案数,那么:
$$f(k)=\binom{n}{k}(2^{2^{n-k}}-1)$$
$$f(k)=\sum _{i=k}^n \binom{i}{k} g(i)$$
设$g(x)$对答案的贡献次数:
$$\sum_{i=0}^x \binom{x}{i} \alpha(i)=[4|x]$$
\begin{align}
\alpha(i)& = \sum_{i = 0}^x \binom{x}{i} [4|x](-1)^{x-i}\\
& = \sum_{i = 0}^x \binom{x}{i} (-1)^{x-i}\frac 14 \sum _{j=0}^3 \omega_4^{ij}\\
& = \frac 14 \sum_{i=0}^n \sum _{j=0}^3 \binom{x}{i} (-1)^{x-i}\omega_4^{ji}\\
& = \frac 14 \sum _{i=0}^3 (\omega_4^j-1)^n
\end{align}
干就完事了
#include<iostream> #include<cstdio> using namespace std; int n,fac[10000005],inv[10000005],w[10000005],f[10000005],a[10000005],ans; const int mod=998244353,inv4=748683265; inline int read(){ int f=1,w=0; char ch=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar(); return f*w; } int ksm(long long a,int p){ long long ret=1; while(p){ if(p&1)(ret*=a)%=mod; (a*=a)%=mod,p>>=1; } return ret; } inline int C(int x,int y){return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;} int main(){ fac[0]=w[0]=1,w[1]=ksm(3,(mod-1)/4),w[2]=1ll*w[1]*w[1]%mod,w[3]=1ll*w[2]*w[1]%mod; for(int i=1;i<=10000000;i++)fac[i]=1ll*fac[i-1]*i%mod; inv[10000000]=ksm(fac[10000000],mod-2); for(int i=9999999;~i;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod; n=read(),f[n]=2; for(int i=n-1;~i;i--)f[i]=1ll*f[i+1]*f[i+1]%mod; for(int i=0;i<=n;i++)f[i]=1ll*(f[i]-1+mod)%mod*C(n,i)%mod; for(int i=0;i<4;i++){ int temp=1; for(int j=0;j<=n;j++)(a[j]+=temp)%=mod,(temp=1ll*temp*(w[i]-1+mod)%mod)%=mod; } for(int i=0;i<=n;i++)(ans+=1ll*a[i]*inv4%mod*f[i]%mod)%=mod; printf("%lld\n",(ans+1)%mod); return 0; }