1 条题解

  • 2
    @ 2026-7-6 19:57:40

    题意

    给定数组 a1,a2,,ana_1,a_2,\dots,a_n,求所有连续区间的元素和之和:

    1lrni=lrai\sum_{1 \le l \le r \le n} \sum_{i=l}^{r} a_i

    暴力思路

    最直接枚举每个区间 [l,r][l,r],再求区间和,如果每次重新求和是 O(n3)O(n^3);用前缀和可以优化到 O(n2)O(n^2)
    但当 nn 很大时,O(n2)O(n^2) 仍然会超时。

    正解
    换一个角度,不枚举区间,而是考虑每个 aia_i 会被多少个区间包含。

    一个区间 [l,r][l,r] 包含 aia_i,需要满足:

    lirl \le i \le r

    左端点 ll 可以选:

    1,2,,i1,2,\dots,i

    一共有 ii 种。

    右端点 rr 可以选:

    i,i+1,,ni,i+1,\dots,n

    一共有 ni+1n-i+1 种。

    所以包含 aia_i 的区间数量是:

    i(ni+1)i(n-i+1)

    因此 aia_i 对答案的总贡献是:

    aii(ni+1)a_i \cdot i \cdot (n-i+1)

    上面这种做法我们可以称为拆贡献

    拆贡献是什么

    拆贡献是一种把“整体求和”改写成“单个对象贡献之和”的思维方式。

    直接枚举所有方案通常很慢。拆贡献的想法是:

    不要枚举每个方案怎么算答案;
    改成枚举每个基本对象,看它在多少个方案中产生贡献。
    

    也就是把:

    方案 Sf(S)\sum_{\text{方案 } S} f(S)

    改写成:

    $$\sum_{\text{基本对象 } x} \text{贡献值}(x) \times \text{出现次数}(x)$$

    它的数学本质是 交换求和顺序

    • 1

    信息

    ID
    199
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    369
    已通过
    54
    上传者