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;
}