LOJ6358 前夕
上来4的倍数又要交集恰好 单位根反演+二项式反演定了(
具体推柿子放下面了qwq
$g(n) = \sum_{i=n}^N f(i) \binom{i}{n} \\g(n) = \binom{N}{n} (2^{2^{N-n}}-1) \\f(n) = \sum_{i=n}^N \binom{i}{n} (-1)^{n-i} g(i) \\ ans = \sum_{n=0}^N [n\%4==0] f(n) \\ans= \sum_{n=0}^N \sum_{j=0}^3 w_4^{nj} f(n) \\ans= \sum_{n=0}^N \sum_{i=n}^N \sum_{j=0}^3 w_4^{nj}(-1)^{i-n}g(i)\binom{i}{n}\\ans= \sum_{i=0}^N (-1)^i g(i) \sum_{n=0}^i \sum_{j=0}^3 w_4^{nj} (-1)^n \binom{i}{n}\\ans= \sum_{i=0}^N (-1)^i g(i) \sum_{j=0}^3 (-w_4^{j}+1)^i$
里面那个-1是为了方便处理空集(不然空集可能加上可能被容斥掉了x)
然后憨憨hywn发现自己不会快速求$2^{2^{N-n}}$ 被大爹suncb教了一发...直接每次平方就好了...我可能是个sbx
于是就做完啦
(第一次推完这么长柿子好感动)
//Love and Freedom. #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define ll long long #define inf 20021225 #define mdn 998244353 #define G 3 #define inv4 748683265ll using namespace std; int read() { int s=0,t=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') t=-1; ch=getchar();} while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar(); return s*t; } int ksm(int bs,int mi) { int ans=1; while(mi) { if(mi&1) ans=1ll*ans*bs%mdn; bs=1ll*bs*bs%mdn; mi>>=1; } return ans; } #define N 10000001 int w[4][2],fac[N],inv[N],g[N]; int C(int n,int m){return n<m?0:1ll*fac[n]*inv[m]%mdn*inv[n-m]%mdn;} int main() { int n=read(); int Wn=ksm(G,(mdn-1)/4); int ans=0; for(int i=0;i<4;i++) w[i][0]=1; for(int i=0;i<4;i++) w[i][1]=(-ksm(Wn,i)+1+mdn)%mdn; fac[0]=1; for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mdn; inv[n]=ksm(fac[n],mdn-2); for(int i=n;i;i--) inv[i-1]=1ll*inv[i]*i%mdn; g[n]=2; for(int i=n;i;i--) g[i-1]=1ll*g[i]*g[i]%mdn; for(int i=0;i<=n;i++) { int val=0; for(int j=0;j<4;j++) (val+=w[j][0])%=mdn,w[j][0]=1ll*w[j][0]*w[j][1]%mdn; (ans+=1ll*(g[i]-1)*C(n,i)%mdn*(i&1?mdn-1:1)%mdn*val%mdn*inv4%mdn)%=mdn; } printf("%d\n",ans+1); return 0; }