[BZOJ4870][Shoi2017]组合数问题(矩阵乘法)

本文探讨了组合数的一个特殊求和问题,并通过递推公式和矩阵快速幂的方法给出了高效的解决方案。利用组合数的重要性质,文章详细推导了递推公式,并通过矩阵乘法解决了边界条件下的大规模计算问题。

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

数学真可怕。

Source

https://www.lydsy.com/JudgeOnline/problem.php?id=4870

Solution

首先,组合数有一个重要的性质:

Cmn=Cmn1+Cm1n1 C n m = C n − 1 m + C n − 1 m − 1

设:
f(m,r)=i=0Cik+rm f ( m , r ) = ∑ i = 0 ∞ C m i k + r

根据组合数的性质推出:
f(m,r)=i=0(Cik+rm1+Cik+(r+k1)modkm1) f ( m , r ) = ∑ i = 0 ∞ ( C m − 1 i k + r + C m − 1 i k + ( r + k − 1 ) mod k )

=i=0Cik+rm1+i=0Cik+(r+k1)modkm1 = ∑ i = 0 ∞ C m − 1 i k + r + ∑ i = 0 ∞ C m − 1 i k + ( r + k − 1 ) mod k

=f(m1,r)+f(m1,(r+k1)modk) = f ( m − 1 , r ) + f ( m − 1 , ( r + k − 1 ) mod k )

边界 f(0,0)=1 f ( 0 , 0 ) = 1
由于 k k 不大,因此用矩阵乘法就能解决这个问题。

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i, a, b) for (i = a; i <= b; i++)
using namespace std; typedef long long ll;
const int N = 55;
int n, PYZ, k, r;
struct cyx {
    int n, m, a[N][N]; cyx() {} cyx(int _n, int _m) : n(_n), m(_m)
        {memset(a, 0, sizeof(a));}
    friend inline cyx operator * (const cyx &a, const cyx &b) {
        int i, j, k; cyx res = cyx(a.n, b.m);
        For (i, 1, res.n) For (j, 1, res.m) For (k, 1, a.m)
            res.a[i][j] = (res.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % PYZ) % PYZ;
        return res;
    }
    friend inline cyx operator ^ (cyx a, ll b) {
        int i; cyx res = cyx(a.n, a.m); For (i, 1, res.n) res.a[i][i] = 1;
        while (b) {
            if (b & 1) res = res * a; a = a * a; b >>= 1;
        }
        return res;
    }
} P, Y, Z;
int main() {
    int i; cin >> n >> PYZ >> k >> r; P = cyx(k, k);
    For (i, 0, k - 1) P.a[i + 1][i + 1]++, P.a[i + 1][(i + k - 1) % k + 1]++;
    Y = cyx(1, k); Y.a[1][1] = 1; Z = Y * (P ^ 1ll * n * k);
    cout << Z.a[1][r + 1] << endl; return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值