1 条题解

  • 0
    @ 2025-10-26 21:34:56

    题意回顾

    给定一个只包含字符 a,b,c\texttt{a}, \texttt{b}, \texttt{c} 的字符串 ss,长度 n3×105n \le 3\times 10^5
    求有多少个连续子串是好的——即子串中出现的各种字符的出现次数完全相同。


    关键观察与转化

    1. 数学表示

    设子串 s[l..r]s[l..r] 中:

    • cnta=\text{cnt}_a = 字符 a\texttt{a} 的出现次数
    • cntb=\text{cnt}_b = 字符 b\texttt{b} 的出现次数
    • cntc=\text{cnt}_c = 字符 c\texttt{c} 的出现次数

    "好的"条件等价于: cnta=cntb=cntc \text{cnt}_a = \text{cnt}_b = \text{cnt}_c


    2. 前缀和表示

    定义前缀和:

    • A[i]=A[i] =ii 个字符中 a\texttt{a} 的个数
    • B[i]=B[i] =ii 个字符中 b\texttt{b} 的个数
    • C[i]=C[i] =ii 个字符中 c\texttt{c} 的个数

    对于子串 s[l..r]s[l..r]: $ \begin{aligned} \text{cnt}_a &= A[r] - A[l-1] \\ \text{cnt}_b &= B[r] - B[l-1] \\ \text{cnt}_c &= C[r] - C[l-1] \end{aligned} $

    条件变为: A[r]A[l1]=B[r]B[l1]=C[r]C[l1] A[r] - A[l-1] = B[r] - B[l-1] = C[r] - C[l-1]


    3. 变量消元与差分表示

    A[r]A[l1]=B[r]B[l1]A[r] - A[l-1] = B[r] - B[l-1] 可得: A[r]B[r]=A[l1]B[l1] A[r] - B[r] = A[l-1] - B[l-1]

    A[r]A[l1]=C[r]C[l1]A[r] - A[l-1] = C[r] - C[l-1] 可得: A[r]C[r]=A[l1]C[l1] A[r] - C[r] = A[l-1] - C[l-1]

    定义两个差分量: $ \begin{aligned} X[i] &= A[i] - B[i] \\ Y[i] &= A[i] - C[i] \end{aligned} $

    则对于子串 s[l..r]s[l..r],"好的"条件等价于: X[r]=X[l1]Y[r]=Y[l1] X[r] = X[l-1] \quad \text{且} \quad Y[r] = Y[l-1]


    问题转化

    我们需要统计满足以下条件的 (l,r)(l, r) 对数(1lrn1 \le l \le r \le n): X[r]=X[l1]Y[r]=Y[l1] X[r] = X[l-1] \quad \text{且} \quad Y[r] = Y[l-1]

    其中 X[0]=Y[0]=0X[0] = Y[0] = 0


    高效算法

    核心思路

    对于每个右端点 rr,统计有多少个 l1[0,r1]l-1 \in [0, r-1] 满足: (X[l1],Y[l1])=(X[r],Y[r]) (X[l-1], Y[l-1]) = (X[r], Y[r])

    这可以用哈希表(或 map)来维护每个 (X,Y)(X, Y) 状态的出现次数。


    算法步骤

    1. 初始化

      • X=0,Y=0X = 0, Y = 0
      • cnt[(0,0)]=1\text{cnt}[(0,0)] = 1
      • ans=0\text{ans} = 0
    2. 遍历右端点 rr11nn

      • 根据 s[r]s[r] 更新 XXYY
        • s[r]=as[r] = \texttt{a}XX+1,YY+1X \gets X+1, Y \gets Y+1
        • s[r]=bs[r] = \texttt{b}XX1,YX \gets X-1, Y 不变
        • s[r]=cs[r] = \texttt{c}XX 不变, YY1Y \gets Y-1
      • ans +=cnt[(X,Y)]\text{ans} \ += \text{cnt}[(X, Y)]
      • cnt[(X,Y)] +=1\text{cnt}[(X, Y)] \ += 1

    正确性说明

    当遇到某个 (X,Y)(X, Y) 状态时,之前所有出现相同状态的位置 l1l-1 都与当前 rr 构成"好的"子串 s[l..r]s[l..r]
    累加这些数量即得到所有以 rr 结尾的"好的"子串数,求和即得答案。


    复杂度分析

    • 时间复杂度O(n哈希操作)O(n \cdot \text{哈希操作}),使用 unordered_map 可达 O(n)O(n)
    • 空间复杂度O(n)O(n),存储不同状态

    总结

    本题的关键在于:

    1. 将"各字符出现次数相同"转化为前缀和的差分条件
    2. 通过定义 X=ABX = A-BY=ACY = A-C 将三维条件降为二维
    3. 使用哈希表统计相同状态的出现次数
    4. 在线性时间内解决问题,可处理 n3×105n \le 3\times 10^5 的大数据
    • 1

    信息

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