牛客多校第一场 B Symmetric Matrix

本文介绍了一种算法,用于计算满足特定条件的n×n矩阵的数量。这些条件包括矩阵元素的范围、对称性以及每行元素之和的固定值。通过将矩阵问题转化为图论中的环问题,文章提出了一种递推公式,并给出了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://ac.nowcoder.com/acm/contest/139/B
来源:牛客网
 

题目描述

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.

 

首先,要想到把矩阵化为图。这个矩阵满足邻接矩阵的性质,考虑每行和为2,即每个点的度为2.

考虑这个图的性质,一定是一些简单环。

假设我们已经求出点为n-1时的情况数,那么考虑加入一个点的情况数。加入一个点一定是要成一个新环的,我们要拿出一些点来与它成环,假设我们拿出了k个点,有C(n,k)种选法,k个点成k!种排列,加一个点成环,对于一个以上的点来说,因为是环所以要除以2.

所以 f (i) = f (i-2)*(i-1) +sigma c(n,n-k)*f(k)*(n-k)!/2

化简一下: f (i) = f (i-2)*(i-1) +sigma (n-1)!/k!*f(k)/2

但是这个式子复杂度显然不对,所以还要继续优化。

考虑 f(i-1) =f(i-3)*(i-2) +sigma(n-2)!/k!*f(k)/2

发现在求和部分如果我们将f(i-1)乘上(n-1),那么和f(i)就只差一项了。

所以 f(i)-f(i-1)*(i-1)=f(i-2)*(i-1)-f(i-3)*(i-2)*(i-1)+f(i-3)*(i-2)*(i-1)/2

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

#include <bits/stdc++.h>

using namespace std;
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define ll long long
#define N 200005
int n,m;
ll f[N];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        if(m==1){puts("0");continue; }
        f[1]=0;f[2]=1;f[3]=1;
        go(i,4,n)f[i]=(f[i-1]*(i-1)+f[i-2]*(i-1)-1ll*(i-2)*(i-1)/2%m*f[i-3]%m+m)%m;
        printf("%lld\n",f[n]);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值