题解:CF1726E Almost Perfect
Demeanor_Roy · · 题解
- 原题链接
考虑对一个排列
- 对于
p 中一任意置换环C ,将C 中的边取反。
故
对于某个环
预处理
对于给定
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10,mod=998244353;
int T,n,f[N],pw[N],inv[N],fct[N],ofct[N],finv[N];
inline int C(int x,int y){return 1ll*fct[x]*finv[y]%mod*finv[x-y]%mod;}
inline void init()
{
f[0]=pw[0]=fct[0]=inv[0]=finv[0]=1;
f[1]=fct[1]=inv[1]=finv[1]=ofct[1]=1;pw[1]=2;
for(int i=2;i<N;i++)
{
pw[i]=pw[i-1]*2%mod;
f[i]=(f[i-1]+1ll*(i-1)*f[i-2])%mod;
fct[i]=1ll*fct[i-1]*i%mod;
inv[i]=(mod-1ll*mod/i*inv[mod%i]%mod)%mod;
finv[i]=1ll*finv[i-1]*inv[i]%mod;
if(i&1) ofct[i]=1ll*ofct[i-2]*i%mod;
}
}
inline int calc(int x){return x>0?ofct[x]:1;}
inline void solve()
{
scanf("%d",&n);
int ans=0;
for(int t=0;t<=n/4;t++) ans=(ans+1ll*C(n-t*2,t*2)*calc(t*2-1)%mod*pw[t]%mod*f[n-t*4])%mod;
printf("%d\n",ans);
}
int main()
{
init();
scanf("%d",&T);
while(T--) solve();
return 0;
}