LOJ 前夕

解题方法:
设F(x)表示至少有i种技能的方案数
显然有:$F(x)=C_{n}^{x} \times 2^{2^{n-x}}$
我们构造容斥函数$f(x)$,令$Ans=\sum f(x) \times F(x)$
题目要求的是所有技能数恰为4k的方案数,所以能得出$[4|x]=\sum\limits_{i=0}^{x} C_{x}^{i}*f[i]$
二项式反演得:$f[x]=\sum\limits_{i=0}^{x} (-1)^{x-i} \times C_{x}^{i}*[4|i]$
$[4|i]$这个东西是可以转化成单位根的式子的,$[4|i]=\frac{1}{4}\sum\limits_{j=0}^{3}\omega^{ij}$
带进去:$f[x]=\frac{1}{4}\sum\limits_{i=0}^{x} (-1)^{x-i} \times C_{x}^{i} \sum\limits_{j=0}^{3} \omega^{ij}$
$=\frac{1}{4}\sum\limits_{j=0}^{3} \sum\limits_{i=0}^{x} (-1)^{x-i} \times C_{x}^{i} \omega^{ij}$
$=\frac{1}{4}\sum\limits_{j=0}^{3}(\omega^{j}-1)^{x}$
我们成功的求出了容斥函数
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dwn(i,a,b) for(int i=a;i>=b;i--)
#define MAXN 10000005
using namespace std;
int read(){
int x=0,f=1;
char ch=getchar();
while(ch>'9' || ch<'0') ch=getchar();
while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x;
}
typedef long long ll;
const ll mod=998244353;
int n;
ll ksm(ll x,ll y){
ll res=1;
while(y){
if(y&1) res=(res*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return res;
}
ll jc=1,ans,inv1=mod-1,a[MAXN],F,now=1,sum,tmp,inv[MAXN],Wn[4],w[4],inv4,f;
void pd(){
if(tmp==1) tmp=inv1;
else tmp=1;
}
ll C(ll x,ll y){
return (jc*inv[x]%mod)*inv[y-x]%mod;
}
int main(){
n=read();
inv[1]=1; inv[0]=1; inv4=ksm(4,mod-2);
a[n]=2; w[0]=w[1]=w[2]=w[3]=1;
rep(i,2,n) inv[i]=((-(mod/i)*inv[mod%i])%mod+mod)%mod,jc=(jc*i)%mod;
rep(i,2,n) inv[i]=inv[i-1]*inv[i]%mod;
Wn[0]=0; Wn[1]=ksm(3,(mod-1)/4)-1; Wn[2]=ksm(3,(mod-1)/2)-1; Wn[3]=ksm(3,((mod-1)/4)*3)-1;
dwn(i,n-1,0) a[i]=(a[i+1]*a[i+1])%mod;
rep(i,0,n) a[i]=(a[i]-1+mod)%mod;
rep(i,0,n){
F=a[i]*C(i,n)%mod;
f=inv4*((w[0]+w[1]+w[2]+w[3])%mod)%mod;
ans=(ans+F*f)%mod;
rep(j,0,3) w[j]=(w[j]*Wn[j])%mod;//,cout<<w[j]<<" ";cout<<endl;
}
printf("%lld",(ans+1)%mod);
return 0;
}

浙公网安备 33010602011771号