1 条题解

  • 0
    @ 2025-10-17 18:46:56

    题解

    设序列为 a1,a2,,aKa_1, a_2, \ldots, a_K,满足 1a1<a2<<aKN1 \le a_1 < a_2 < \cdots < a_K \le N 且相邻差值 di=aiai1d_i = a_i - a_{i-1}i2i \ge 2)都不超过 MM。对任意一组差值序列 (d2,,dK)(d_2,\ldots,d_K),如果把它们的和记为 SS,则 aK=a1+Sa_K = a_1 + S。由于 SM(K1)<NS \le M (K-1) < N,总能选出合法的 a1a_1,且 a1a_1 可以取 1NS1 \sim N - S 的任意整数。因此对于固定的差值组合,合法序列的数量恰为 NSN - S

    所有差值相互独立,且每个 did_iMM 种取值,所以共有 MK1M^{K-1} 组差值序列。于是答案为

    (NS)=NMK1S.\sum (N - S) = N \cdot M^{K-1} - \sum S.

    S\sum S 可以拆分:每个位置的差值在所有组合中出现 MK2M^{K-2} 次,差值取值之和为 M(M+1)2\frac{M(M+1)}{2},一共有 K1K-1 个位置,因而

    $$\sum S = (K-1) \cdot M^{K-2} \cdot \frac{M(M+1)}{2}. $$

    把上述公式整理后再对模数 PP 取模即可。代码中使用快速幂求出 MK2M^{K-2},再套用推导出的闭式公式。

    #include <iostream>
    
    int main() {
        long long N, M, K, P;
        std::cin >> N >> K >> M >> P;
        
        long long s = 1, x = K - 2, n = M;
        for (; x; x /= 2, n = n * n % P)
            if (x & 1)
                s = s * n % P;
        
        std::cout << s * (N % P * M % P - (M + 1) * M / 2 % P * (K - 1) % P + P) % P << '\n';
        return 0;
    }
    
    • 1

    信息

    ID
    3257
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者