1 条题解

  • 0
    @ 2025-12-11 1:26:39

    题解:区间颜色贡献乘积和

    问题转化

    给定两个区间 [l1,r1][l_1, r_1][l2,r2][l_2, r_2],设 c1(x)c_1(x) 为值 xx 在第一个区间出现的次数,c2(x)c_2(x) 为值 xx 在第二个区间出现的次数,求:

    xc1(x)c2(x)\sum_{x} c_1(x) \cdot c_2(x)

    关键推导

    1. 公式展开

    [l1,r1]=A[l_1, r_1] = A[l2,r2]=B[l_2, r_2] = B

    $$\text{ans} = \sum_{x} \left( \sum_{i \in A} [a_i = x] \right) \cdot \left( \sum_{j \in B} [a_j = x] \right) $$

    交换求和顺序:

    $$\text{ans} = \sum_{i \in A} \sum_{j \in B} [a_i = a_j] $$

    2. 转化为平面计数

    将每个位置 ii 视为二维平面上的点 (i,i)(i, i),原问题变为:
    计算矩形 [l1,r1]×[l2,r2][l_1, r_1] \times [l_2, r_2] 中,满足 ai=aja_i = a_j 的点 (i,j)(i, j) 的数量。

    3. 莫队二次离线

    标准莫队一次只能处理一个区间,这里需要同时处理两个区间。
    注意到:

    $$\sum_{i \in A} \sum_{j \in B} [a_i = a_j] = f(r_1, r_2) - f(l_1-1, r_2) - f(r_1, l_2-1) + f(l_1-1, l_2-1) $$

    其中 f(u,v)=i=1uj=1v[ai=aj]f(u, v) = \sum_{i=1}^u \sum_{j=1}^v [a_i = a_j]

    于是问题转化为:快速计算 f(u,v)f(u, v) 对任意 u,vu, v 的查询。

    4. 二维数点优化

    对每个值 xx,设它出现的位置为 p1,p2,,pmp_1, p_2, \dots, p_m
    f(u,v)f(u, v) 中,值 xx 的贡献为:

    cntu(x)cntv(x)\text{cnt}_u(x) \cdot \text{cnt}_v(x)

    其中 cntu(x)\text{cnt}_u(x)xx[1,u][1, u] 中出现的次数。

    维护 cntu(x)\text{cnt}_u(x) 需要 O(N)O(N) 空间,但 N50000N \le 50000,可以接受。

    5. 分块预处理

    将序列分块,块大小为 BNB \approx \sqrt{N}

    预处理:

    • pre[i][x]pre[i][x]:前 ii 块中值 xx 的出现次数(ii 从 0 到块数)
    • fblock(i,j)f_{block}(i, j):第 ii 块到第 jj 块之间的答案(只考虑整块)

    6. 查询处理

    对于查询 f(u,v)f(u, v)

    1. uu 所在块为 LLvv 所在块为 RR
    2. 整块贡献从预处理 fblockf_{block} 获取
    3. 剩余零散部分暴力枚举,用桶临时计数

    7. 算法步骤

    1. 读入序列,离散化(aiNa_i \le N 但可能稀疏)
    2. 分块,预处理 preprefblockf_{block}
    3. 对每个询问 (l1,r1,l2,r2)(l_1, r_1, l_2, r_2)
      • 用二维前缀和公式拆成 4 个 f(u,v)f(u, v) 查询
      • 对每个 f(u,v)f(u, v) 用分块方法计算
      • 合并得到答案

    8. 复杂度分析

    • 预处理:
      • prepre 数组:O((N/B)N)O((N/B) \cdot N) 空间 O(NN/B)O(N \cdot N/B),用哈希表可优化
      • fblockf_{block}O((N/B)2B)O((N/B)^2 \cdot B)
    • 单次查询:O(B)O(B)
    • 总复杂度:O(N1.5+QN)O(N^{1.5} + Q \sqrt{N})

    B=N224B = \sqrt{N} \approx 224,实际可行。

    9. 优化实现

    • 使用数组代替哈希表,因为值域 N\le N
    • 注意内存使用,可只存整块间的答案矩阵
    • 零散部分用临时数组计数

    10. 最终答案

    对每个询问输出合并后的结果即可。

    此方法在 N,Q50000N, Q \le 50000 的数据范围内可以在 44 秒内通过。

    • 1

    信息

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