本题主要是对用容斥的使用,正难则反,对于要求满足题意的可以求不满足题意的
先考虑对于长度至少为2的连续序列,易得其排列C(n,1)*(n-2)!,意为从剩下n个数字中选取连续的两个。
方法总计为n,即从n种中选取一个,剩下所有元素进行全排列
由此可以类比到选取k(0-n-1)个连续的元素,即排列总数为C(n,k)(n-k-1)!
当k==n为一个的时候答案总为1
再运用容斥的原理可以得到其为
ans=(-1)^n+sum((-1)^k*c(n,k)(n-k-1)!,0-(n-1))
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; const int mod=998244353; typedef long long int ll; ll pre[maxn+5],inv[maxn+5],n; ll powmod(ll a,ll b) { ll ans=1; a=a%mod; while(b) { if(b&1)ans=(a%mod*ans%mod)%mod; a=(a%mod*a%mod)%mod; b>>=1; } return ans%mod; } ll c(ll n,ll m) { return 1ll*((pre[n]%mod*inv[n-m]%mod)%mod*inv[m]%mod)%mod; } void solve() { scanf("%d",&n); ll ans=((n%2==0)?1:mod-1); for(int i=0; i<n; i++) { ll an=(c(n,i)%mod*pre[n-i-1]%mod)%mod; if(i&1) { (ans += mod- an) %= mod; } else { (ans += an) %= mod; } } printf("%lld ",(ans+mod)%mod); } int main() { pre[0]=1; for(int i=1; i<=maxn; i++) { pre[i]=(pre[i-1]%mod*i%mod)%mod; } inv[maxn]=powmod(pre[maxn],mod-2); for(int i=maxn-1; i>=0; i--) { inv[i]=(inv[i+1]%mod*(i+1)%mod)%mod; } int t; for(scanf("%d",&t); t; t--) { solve(); } return 0; }