原题链接:https://judge.yosupo.jp/problem/montmort_number_mod
Montmort Number
Let ak be the number of size k permutations p s.t. pi=i for each i.
Given N,M. For each i=1,⋯,N, print bk=akmodM.
Constraints
1≤N≤106
1≤M≤109
N M
Output
b1 b2 ... bn
Sample
#1
1 2
| 10 100 0 1 2 9 44 65 54 33 96 61
|
#2
1 2
| 20 998244353 0 1 2 9 44 265 1854 14833 133496 1334961 14684570 176214841 294304226 127281753 910981941 600290115 222488424 11814221 224470198 496426549
|
题目描述
设1...k共k个数,排列这k个数,共有k!中可能,设其中一种排列为p,pi表示第i个数的值,ak表示满足所有i的情况下pi=i的排列的个数;
例如:k=2,共有2!=2种排列,分别为{1,2},{2,1},满足pi=i的排列只有一种,即{2,1}
输入N,M,对于每一个k=1,⋯,N,求akmodM的值
解决方案
a0=1,我的理解是,没有东西可以排列的情况有1种,即{}
a1=0,只有{1}一种排列,该排列不满足pi=i
对于ak来说,第1个位置的数有k−1种可能(即2,3,...,k之一),假设把i放在第1个位置,这时有2种选择
- 把1放到第i个位置,这时剩下的k−2个位置分别都存在对应的数字,成为了一个子问题,即ak−2
- 1不放到第i个位置,这样便相当于1不能放在第i个位置,相当于一个k−1个数的子问题,即ak−1
因此
⎩⎨⎧a0=1,a1=0,ak=(k−1)∗(ak−1+ak−2),k≥2
时间复杂度
O(n)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <iostream>
int main() { int n,m; while(cin>>n>>m) { vi f(n+1, 0); a[0] = 1; a[1] = 0; cout << 0; rep(k,2,n+1) { a[k] = ((ll)(k-1) * (a[k-1] + a[k-2])) % m; cout << " " << f[k]; } cout << endl; } }
|