生成树计数(和MOD取模)

本文介绍了一种计算矩阵行列式的值模上MOD的方法,包括逆元的求解及行列式的计算。

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

 
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD = 10007;
int INV[MOD];
//求ax = 1( mod m) 的x值,就是逆元(0<a<m)
long long inv(long long a,long long m) {
    if(a == 1)return 1;
    return inv(m%a,m)*(m-m/a)%m;
}
struct Matrix {
    int mat[330][330];
    void init() {
        memset(mat,0,sizeof(mat));
    }
    void addEdge(int u,int v) {
        mat[u][v]=-1;
        mat[u][u]++;
    }
    int det(int n) { //求行列式的值模上MOD,需要使用逆元
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                mat[i][j] = (mat[i][j]%MOD+MOD)%MOD;
        int res = 1;
        for(int i = 0; i < n; i++) {
            for(int j = i; j < n; j++)
                if(mat[j][i]!=0) {
                    for(int k = i; k < n; k++)
                        swap(mat[i][k],mat[j][k]);
                    if(i != j)
                        res = (-res+MOD)%MOD;
                    break;
                }
            if(mat[i][i] == 0) {
                res = -1;//不存在(也就是行列式值为0)
                break;
            }
            for(int j = i+1; j < n; j++) {
                //int mut = (mat[j][i]*INV[mat[i][i]])%MOD;//打表逆元
                int mut = (mat[j][i]*inv(mat[i][i],MOD))%MOD;
                for(int k = i; k < n; k++)
                    mat[j][k] = (mat[j][k]-(mat[i][k]*mut)%MOD+MOD)%MOD;
            }
            res = (res * mat[i][i])%MOD;
        }
        return res;
    }
};
Matrix ret;
int main() {
    int t;
    cin>>t;
    while(t--) {
        int n,m;
        scanf("%d%d",&n,&m);
        ret.init();
        for(int i=0;i<m;i++){
           int u,v;
           scanf("%d%d",&u,&v);
           ret.addEdge(u,v);
           ret.addEdge(v,u);
        }
        printf("%d\n",ret.det(n-1));
    }
    return 0;
}

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int N = 1010; 7 8 int n, m, mod; 9 long long ans, y[N], f[N], g[N], p[N], s[N]; 10 11 long long qmi(long long a, int b, int p) { 12 long long res = 1; 13 while (b) { 14 if (b & 1) 15 res = res * a % p; 16 a = a * a % p; 17 b >>= 1; 18 } 19 return res; 20 } 21 22 long long solve(int n, int k) { 23 memset(y, 0, sizeof(y)); 24 memset(f, 0, sizeof(f)); 25 memset(g, 0, sizeof(g)); 26 memset(p, 0, sizeof(p)); 27 memset(s, 0, sizeof(s)); LUOGU SCP-S 2025 第一轮 C++语言试题 第 6 页,共 17 页 28 long long ans = 0; 29 for (int i = 1; i <= k + 2; i++) 30 y[i] = (y[i - 1] + qmi(i, k, mod)) % mod; 31 f[0] = g[0] = 1; 32 for (int i = 1; i <= k + 2; i++) 33 f[i] = f[i - 1] * i % mod; 34 for (int i = 1; i <= k + 2; i++) 35 g[i] = -g[i - 1] * i % mod; 36 p[0] = s[k + 3] = 1; 37 for (int i = 1; i <= k + 2; i++) 38 p[i] = p[i - 1] * (n - i) % mod; 39 for (int i = k + 2; i >= 1; i--) 40 s[i] = s[i + 1] * (n - i) % mod; 41 for (int i = 1; i <= k + 2; i++) { 42 long long t1 = p[i - 1] * s[i + 1] % mod; 43 long long t2 = f[i - 1] * g[abs(k - i + 2)] % mod; 44 (ans += y[i] * t1 % mod * qmi(t2, mod - 2, mod) % mod) %= mod; 45 ans = (ans + mod) % mod; 46 } 47 return ans; 48 } 49 50 int main() { 51 scanf("%d%d%d", &n, &m, &mod); 52 long long res = 0; 53 for (int i = 1; i <= n; i++) { 54 res += (n - i + 1) * qmi(m, n - i, mod) % mod * solve(m, i); 55 res %= mod; 56 } 57 printf("%lld", res); 58 return 0; 59 } 假设输入的 𝒏, 𝒎 是不超过 𝟏𝟎𝟎𝟎 的正整数,mod 是大于 𝟏𝟎 𝟒,但是不超过 𝟏𝟎 𝟗 + 𝟕 的质 数,完成下面的判断题单选题。 ·判断题 21. qmi 函数实现了快速幂算法。该函数对于任意的不超过 109 + 7 的非负整数 b 不超 LUOGU SCP-S 2025 第一轮 C++语言试题 第 7 页,共 17 页 过 109 + 7 的正整数 a,p 均能正确返回 𝑎 𝑏 对 𝑝 的值。( ) 22. 删除程序的第 23 到 27 行,程序仍然能正常运行,且输出结果不变。( ) 23. 当输入的 𝑚 为 1 时,输出总为 𝑛(𝑛 2 +1)。( ) ·单选题 24. 这份程序的最坏时间复杂度是( )。 A. Θ(𝑛 2 ) B. Θ(𝑛 log 𝑛) C. Θ(𝑛 2 log 𝑛) D. Θ(𝑛 2 log(𝑛 × mod)) 25. 对于以下的输入数据,输出结果为( )。 3 4 10331 A. 1900 B. 9500 C. 820 D. 1650 26. (4 分)这份程序得了( )的答案对 mod 的结果。 A. 对于所有长度为 𝑛 的,值域为 [1, 𝑚] 的整数序列 𝑎,计算 ∑ ∑ max𝑘 𝑗 =𝑖 𝑎𝑘 𝑛 𝑗=𝑖 𝑛 𝑖=1 之。 B. 对于所有长度为 𝑚 的,值域为 [1, 𝑛] 的整数序列 𝑎,计算 ∑ ∑ max𝑘 𝑗 =𝑖 𝑎𝑘 𝑚 𝑗=𝑖 𝑚 𝑖=1 之。 C. 对于所有长度为 𝑛 的,值域为 [1, 𝑚] 的整数序列 𝑎,计算 ∑ ∑ min𝑘 𝑗 =𝑖 𝑎𝑘 𝑛 𝑗=𝑖 𝑛 𝑖=1 之。 D. 对于所有长度为 𝑚 的,值域为 [1, 𝑛] 的整数序列 𝑎,计算 ∑ ∑ min𝑘 𝑗 =𝑖 𝑎𝑘 𝑚 𝑗=𝑖 𝑚 𝑖=1 之
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值