Symmetric Matrix Gym - 247727B
Count the number of n×n matrices A satisfying the following condition modulo m.
-
Ai,j∈{0,1,2} for all 1≤i,j≤n.
-
Ai,j=Aj,i for all 1≤i,j≤n.
-
Ai,1+Ai,2+⋯+Ai,n=2 for all 1≤i≤n.
-
A1,1=A2,2=⋯=An,n=0.
Input
The input consists of several test cases and is terminated by end-of-file.
Each test case contains two integers n and m.
- 1≤n≤105
- 1≤m≤109
- The sum of n does not exceed 107.
Output
For each test case, print an integer which denotes the result.
Input
3 1000000000
100000 1000000000
Output
1
507109376
求满足以上条件的矩阵有多少个
- 可以把这个矩阵看做一个无向图的邻接矩阵,每个点的度都为2,而且可以有重边,没有自环,这就意味着,每个点属于且仅属于一个环(也会存在两个点,两条边组成的环),这个问题就可以转化成了计算满足这些条件的图的个数
- 可以用递推来计算,F[n]代表n个点的答案
- F[1] = 0,F[2] = 1,F[3] = 1
- 当有n个点的时候,第n个点可以拿之前n-1个点中的一个与自己组环,个数是(n-1)*F[n-2]
- 当从前n-1个点中留下k个点,也就是取n-k-1个点与第n个点组成环的时候,种数是C(n-1,k) * F[k] *(n-k)!/(n-k)/2 =C(n-1,k) * F[k] *(n-k-1)!/2
(ps:m个点的循环全排列的个数是m!/m = (m-1)!,因为环54321和12345在邻接矩阵中的表现形式一样,所以结果除2) - 所以F[n] = (n-1)* F[n-2]+(k from 0 to n-3):C(n-1,k) * F[k] *(n-k-1)!/2,然后要通过公式化简转化为递推式
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+9;
long long f[maxn];
int main()
{
long long i,j,mod,n;
while(scanf("%lld %lld",&n,&mod)!=EOF)
{
f[1]=0;
f[2] =1;
f[3] = 1;
for(i = 4;i<=n;i++)
{
f[i] = ((i-1)*f[i-1]%mod+(i-1)*f[i-2]%mod-(i-1)*(i-2)/2*f[i-3]%mod+mod)%mod;
}
cout<<f[n]<<endl;
}
return 0;
}