Symmetric Matrix Gym - 247727B

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,然后要通过公式化简转化为递推式
  • Symmetric Matrix Gym - 247727B_第1张图片
#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;
}

你可能感兴趣的:(Symmetric Matrix Gym - 247727B)