1≤n≤500000
Solution
我们设 fi f i 表示长度为i的错排,容斥后易得答案
代码
#include <bits/stdc++.h>
typedef long long LL;
const int N = 500005;
const int MOD = 1000000007;
int n,jc[N],ny[N],f[N];
int C(int n,int m)
{
return (LL)jc[n] * ny[m] % MOD * ny[n - m] % MOD;
}
int main()
{
scanf("%d",&n);
jc[0] = jc[1] = ny[0] = ny[1] = 1;
for (int i = 2; i <= n; i++)
jc[i] = (LL)jc[i - 1] * i % MOD, ny[i] = (LL)(MOD - MOD / i) * ny[MOD % i] % MOD;
for (int i = 2; i <= n; i++)
ny[i] = (LL)ny[i - 1] * ny[i] % MOD;
f[0] = f[2] = 1;
for (int i = 3; i <= n; i++)
f[i] = (LL)(i - 1) * (f[i - 1] + f[i - 2]) % MOD;
int ans = 0;
for (int i = 2; i <= n; i++)
{
int w = 1;
for (int j = 1; j * i <= n; j++)
{
w = (LL)w * C(n - i * (j - 1), i) % MOD * jc[i - 1] % MOD;
if (j & 1)
(ans += (LL)w * f[n - i * j] % MOD * ny[j] % MOD) %= MOD;
else (ans += MOD - (LL)w * f[n - i * j] % MOD * ny[j] % MOD) %= MOD;
}
}
printf("%d",ans);
}