牛客网暑期ACM多校训练营(第一场)B

2. Count the number of n x 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. 输入描述: The input consists of several test cases and is terminated by end-of-file. Each test case contains two integers n and m. 输出描述: For each test case, print an integer which denotes the result. 备注 * 1 ≤ n ≤ 105 * 1 ≤ m ≤ 109 * The sum of n does not exceed 10 7. 


输入
3 1000000000 
100000 1000000000 
输出
1

507109376

题意:一个方阵阵由0,1,2组成,对角线元素为0,且为对称矩阵,且每一行相加为2。给出方阵大小,问满足条件的有多少种。

来自:https://blog.csdn.net/lifelikes/article/details/81123882

解题思路: 
题目给出的合法矩阵是一个类似与邻接矩阵的样式。 所以应该往这方面去考虑。 
每行之和等于2 , 代表每个点都连有两条边,可以有重边 不能有自环。 
这说明 每个点属于且仅属于一个环。 
因为输入只有一个n 
应该要往dp递推的方向上去想。

现在开始找递推式。 
定义dp[n]表示n个点构成的合法图的方案数。 
思考每加入一个新球,如何从已知状态转移。 
考虑从前面的n-1个球中选取一些球和新球组成一个环。 
1,特殊考虑只取一个旧球的情况, 
     这种情况下这个旧球有n-1种方案 剩下的n-2个球组成的合法方案数已经求出。 
     所以这种情况下 方案数为(n-1)f(n-1) 

2,当我们取n-k个旧球,有C(n-1,n-1-k)=C(n-1,k),剩下k个自成体系f(k),考虑n-k-1个球与一个新球构成环有(n-k-1)!种,考虑换左右对称要除2。所以就有了dp[n] = (n-1) dp[n-2] + sigma(x:2->n-3)((n-1)!/(2*x!)dp[x]) 。然后化简一下就可以得到

f[i]=(i-1)*(f[i-1]+f[i-2])-(i-1)*(i-2)*f[i-3]/2

ll f[100050];
int main()
{
    ll n,mod;
    while(scanf("%d%d",&n,&mod)!=EOF)
    {
        f[0]=1%mod;f[1]=0;f[2]=1%mod;f[3]=1%mod;
        for(long long i=3;i<=n;i++)      //注意i用long long
        {
            f[i]=(((i-1)*(f[i-1]+f[i-2]))%mod-((i-1)*(i-2)/2*(f[i-3]))%mod+mod)%mod;
        }
        printf("%lld\n",f[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/snayf/article/details/81139140