1 条题解

  • 0
    @ 2025-8-24 21:52:17

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar jiangly
    这个家伙很菜,什么也没有留下

    搬运于2025-08-24 21:52:17,当前版本为作者最后更新于2019-12-11 21:37:05,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意

    给定 nn, pp, rr, kk (1n1091\le n\le 10^9, 0r<k500\le r<k\le 50, 2p23012\le p\le 2^{30}-1),求

    imodk=r(nki)modp\sum_{i\bmod k=r}{nk\choose i}\bmod p

    题解

    $$\begin{aligned}&\sum_{i\bmod k=r}{nk\choose i}\\=&\sum_{i\bmod k=r}[x^i](1+x)^{nk}\\=& [x^r]\left((1+x)^{nk}\bmod(x^k-1)\right)\end{aligned} $$

    直接循环卷积快速幂,时间复杂度 O(k2(logn+logk))O(k^2(\log n+\log k))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int p, k;
    vector<int> operator*(const vector<int> &lhs, const vector<int> &rhs) {
        vector<int> result(k);
        for (int i = 0; i < k; ++i)
            for (int j = 0; j < k; ++j)
                result[(i + j) % k] = (result[(i + j) % k] + 1LL * lhs[i] * rhs[j]) % p;
        return result;
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, r;
        cin >> n >> p >> k >> r;
        vector<int> a(k), ans(k);
        if (k == 1) {
            a[0] = 2 % p;
        } else {
            a[0] = a[1] = 1;
        }
        ans[0] = 1;
        auto e = 1LL * n * k;
        while (e > 0) {
            if (e & 1)
                ans = ans * a;
            a = a * a;
            e >>= 1;
        }
        cout << ans[r] << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    1340
    时间
    1000ms
    内存
    512MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者