1 条题解

  • 0
    @ 2026-8-21 21:33:36

    题解

    思路

    按右端点从左到右统计。固定右端点 rr,记所有以 rr 结尾的子数组的不同元素个数为 Dl=f(l,r)D_l=f(l,r),需要维护 Sr=l=1rDl2S_r=\sum_{l=1}^{r}D_l^2

    ppArA_r 上一次出现的位置;若此前没有出现,则 p=0p=0。加入 ArA_r 后,左端点在 [p+1,r][p+1,r] 内的子数组恰好新增一种不同元素,其余子数组不变。因此

    $$S_r=S_{r-1}+2\sum_{l=p+1}^{r}D_l^{\mathrm{old}}+(r-p).$$

    这里令加入新位置前的空子数组对应值为零。

    考虑某个此前出现过的值,设它最后出现于位置 tt。它会对 DloldD_l^{\mathrm{old}} 贡献一,当且仅当 ltl\le t。所以它对区间 l[p+1,r]l\in[p+1,r] 的总贡献是 max(0,tp)\max(0,t-p)。于是所需的旧值之和为

    t>p(tp)=t>ptp#{t>p},\sum_{t>p}(t-p)=\sum_{t>p}t-p\cdot\#\{t>p\},

    其中每种不同的值只保留其最后出现位置。

    做法

    分别用两棵树状数组维护所有当前最后出现位置的数量和位置之和。处理 ArA_r 时,在后缀 (p,n](p,n] 上查询数量与位置和,代入上式更新 SrS_r,再将 SrS_r 加入总答案。随后删除旧位置 pp,插入新位置 rr

    n100n\le100 时,可以枚举左端点并逐步扩展右端点,用集合维护不同值数量。

    若所有元素相等,每个子数组的 ff 都是一,答案为子数组总数 n(n+1)/2n(n+1)/2

    若所有元素互不相同,长度为 LL 的子数组有 nL+1n-L+1 个且 f=Lf=L,求和可化为

    $$\sum_{L=1}^{n}(n-L+1)L^2=\frac{n(n+1)^2(n+2)}{12}.$$

    正确性说明

    加入 ArA_r 时,只有不包含其上一次出现位置的子数组会增加一种不同元素,因此受影响左端点恰为 [p+1,r][p+1,r]。平方差恒为 (D+1)2D2=2D+1(D+1)^2-D^2=2D+1,故转移式正确。

    对任意旧值,只保留最后出现位置 tt 即可判断它是否出现在子数组 [l,r1][l,r-1] 中;它在所有受影响左端点中的贡献次数正是 max(0,tp)\max(0,t-p)。两棵树状数组精确维护这些最后位置的数量与和,所以每次得到的旧值之和正确。逐个累加所有 SrS_r 即覆盖且只覆盖全部子数组。

    复杂度

    离散化需要排序。每个位置执行常数次树状数组操作,总时间复杂度为 O(nlogn)O(n\log n),空间复杂度为 O(n)O(n)

    • 1

    信息

    ID
    949
    时间
    2000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者