NC17134 Symmetric Matrix

NC17134 Symmetric Matrix

Problem Statement

数有多少个 n × n n\times n n×n的矩阵满足下列条件:

  • A i , j ∈ { 0 , 1 , 2 } , 1 ≤ i , j ≤ n A_{i,j}\in\{0,1,2\},1\leq i,j\leq n Ai,j{0,1,2},1i,jn.
  • A i , j = A j , i , 1 ≤ i , j ≤ n A_{i,j}=A_{j,i},1\leq i,j\leq n Ai,j=Aj,i,1i,jn.
  • ∑ i = 1 n A j , i = 2 , j ∈ [ 1 , n ] \sum_{i=1}^nA_{j,i}=2,j\in[1,n] i=1nAj,i=2,j[1,n].
  • A i , i = 0 , i ∈ [ 1 , n ] A_{i,i}=0,i\in[1,n] Ai,i=0,i[1,n].

Solution

由于性质 2 2 2可知, A A A是一个对称矩阵. 因此我们可以把 A A A看作为一个 n n n个点的无向图的邻接矩阵.

那问题就转化成, 有 n n n个点, 每个点的度数都是 2 2 2, 且不存在自环, 但是允许有重边(重边当且仅当在二元环中出现).

那么我们考虑递推/第二类数学归纳法,

f k f_k fk表示 k k k个点满足上述要求的方案数.

k ≤ n − 1 k\leq n-1 kn1 f k f_k fk已经求出了. 现在我们通过 f k , k ≤ n − 1 f_k,k\leq n-1 fk,kn1去求 f n f_n fn.

现在添加了一个点, 它需要和之前存在的一个点形成环.

如果添加的一个点和之前的点形成了一个二元环的方案数是 ( n − 1 ) f n − 2 (n-1)f_{n-2} (n1)fn2.

如果添加的一个点和之前的点形成了一个 k k k元环, 得方案数 ∑ k = 0 n − 3 ( C n − 1 k × f k × ( n − k − 1 ) ! 2 ) \sum_{k=0}^{n-3}(C_{n-1}^k\times f_k\times\frac{(n-k-1)!}{2}) k=0n3(Cn1k×fk×2(nk1)!).

  • f n = ( n − 1 ) f n − 2 + ∑ k = 0 n − 3 ( n − 1 ) ! 2 × k ! f k f_n=(n-1)f_{n-2}+\sum_{k=0}^{n-3}\frac{(n-1)!}{2\times k!}f_k fn=(n1)fn2+k=0n32×k!(n1)!fk.

  • f n − 1 = ( n − 2 ) f n − 3 + ∑ k = 0 n − 4 ( n − 2 ) ! 2 × k ! f k f_{n-1}=(n-2)f_{n-3}+\sum_{k=0}^{n-4}\frac{(n-2)!}{2\times k!}f_k fn1=(n2)fn3+k=0n42×k!(n2)!fk.

f n − ( n − 1 ) f n − 1 = ( n − 1 ) f n − 2 + ∑ k = 0 n − 3 ( n − 1 ) ! 2 × k ! f k − ( n − 1 ) ( n − 2 ) f n − 3 − ∑ k = 0 n − 4 ( n − 1 ) ! 2 × k ! f k f_n-(n-1)f_{n-1}=(n-1)f_{n-2}+\sum_{k=0}^{n-3}\frac{(n-1)!}{2\times k!}f_k-(n-1)(n-2)f_{n-3}-\sum_{k=0}^{n-4}\frac{(n-1)!}{2\times k!}f_k fn(n1)fn1=(n1)fn2+k=0n32×k!(n1)!fk(n1)(n2)fn3k=0n42×k!(n1)!fk.

化简可得 f n = ( n − 1 ) ( f n − 1 + f n − 2 ) − ( n − 1 ) ( n − 2 ) 2 f n − 3 f_n=(n-1)(f_{n-1}+f_{n-2})-\frac{(n-1)(n-2)}{2}f_{n-3} fn=(n1)(fn1+fn2)2(n1)(n2)fn3.

边界: f 1 = 0 , f 2 = f 3 = 1 f_1=0,f_2=f_3=1 f1=0,f2=f3=1.

算法复杂度为 O ( n ) O(n) O(n).

Code

# define Fast_IO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
# include "unordered_map"
# include "algorithm"
# include "iostream"
# include "cstdlib"
# include "cstring"
# include "cstdio"
# include "vector"
# include "bitset"
# include "queue"
# include "cmath"
# include "map"
# include "set"

using namespace std;

const int maxm=1e5+10;

int N,Mod;
long long DP[maxm];

int main(){
	static long long i;
	while(~scanf("%d%d",&N,&Mod)){
		DP[1]=0,DP[2]=DP[3]=1;
		for(i=4;i<=N;i++){
			DP[i]=((i-1)*(DP[i-1]+DP[i-2])-(i-1)*(i-2)/2*DP[i-3]%Mod+Mod)%Mod;
		}printf("%lld\n",(DP[N]+Mod)%Mod);
	}
	return 0;
}

Link

Link 1: NC17134 Symmetric Matrix

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值