Codeforces Round 1042 (Div. 3)

本文最后更新于 2 分钟前,文中所描述的信息可能已发生改变。

Problem - F - Codeforces

题目类型

#数论 #前缀和 #二分

解题思路

通过公式推理,转换求解函数,通过二分查找 prea(x) = preb(y) 的分界点,然后通过前缀和求累加和,公式推理如下:

min(A,B)=A+B2AB2\min(A, B) = \frac{A + B}{2} - \frac{|A - B|}{2}

f(x,y)=min(cnt0(x,y),cnt1(x,y))=cnt0(x,y)+cnt1(x,y)2cnt0(x,y)cnt1(x,y)2=x+y2cnt0(x,y)cnt1(x,y)2\begin{aligned} f(x, y) &= \min(\text{cnt}_0(x, y), \text{cnt}_1(x, y)) \\ &= \frac{\text{cnt}_0(x, y) + \text{cnt}_1(x, y)}{2} - \frac{|\text{cnt}_0(x, y) - \text{cnt}_1(x, y)|}{2} \\ &= \frac{x + y}{2} - \frac{|\text{cnt}_0(x, y) - \text{cnt}_1(x, y)|}{2} \end{aligned}

f(x,y)=x+y2cnt0(x,y)cnt1(x,y)2=n2(n+1)2cnt0(x,y)cnt1(x,y)2\begin{aligned} \sum f(x, y) &= \sum \frac{x + y}{2} - \sum \frac{|\text{cnt}_0(x, y) - \text{cnt}_1(x, y)|}{2} \\ &= \frac{n^2(n + 1)}{2} - \frac{\sum |\text{cnt}_0(x, y) - \text{cnt}_1(x, y)|}{2} \end{aligned}

cnt0(x,y)cnt1(x,y)=cnt0(x,0)+cnt0(0,y)cnt1(x,0)+cnt1(0,y)=(cnt0(x,0)cnt1(x,0))(cnt1(0,y)cnt0(0,y))\begin{aligned} |\text{cnt}_0(x, y) - \text{cnt}_1(x, y)| &= |\text{cnt}_0(x, 0) + \text{cnt}_0(0, y) - \text{cnt}_1(x, 0) + \text{cnt}_1(0, y)| \\ &= |(\text{cnt}_0(x, 0) - \text{cnt}_1(x, 0)) - (\text{cnt}_1(0, y) - \text{cnt}_0(0, y))| \end{aligned}

prea(x)=cnt0(x,0)cnt1(x,0)preb(y)=cnt1(0,y)cnt0(0,y)\begin{aligned} \text{prea}(x) &= \text{cnt}_0(x, 0) - \text{cnt}_1(x, 0) \\ \text{preb}(y) &= \text{cnt}_1(0, y) - \text{cnt}_0(0, y) \end{aligned}

cnt0(x,y)cnt1(x,y)=prea(x)preb(y)|\text{cnt}_0(x, y) - \text{cnt}_1(x, y)| = |\text{prea}(x) - \text{preb}(y)|

参考:Codeforces Round 1042 (Div. 3) Editorial - Codeforces

示例代码

python
def helltractor():
    for _ in range(II()):
        n = II()
        a = I()
        b = I()

        a0 = [0] * (n + 1)
        a1 = [0] * (n + 1)
        b0 = [0] * (n + 1)
        b1 = [0] * (n + 1)
        for i in range(n):
            a0[i + 1] = a0[i] + (a[i] == "0")
            a1[i + 1] = i + 1 - a0[i + 1]
            b0[i + 1] = b0[i] + (b[i] == "0")
            b1[i + 1] = i + 1 - b0[i + 1]

        delta_a = [a0[i] - a1[i] for i in range(n + 1)]
        delta_b = [b1[i] - b0[i] for i in range(1, n + 1)]
        delta_b.sort()

        sum_db = list(accumulate(delta_b, initial=0))
        res = 0
        for x in range(1, n + 1):
            val = delta_a[x]
            idx = bisect_left(delta_b, val)
            res += val * idx - sum_db[idx]
            res += (sum_db[n] - sum_db[idx]) - val * (n - idx)

        ans = n * n * (n + 1) / 2 - res / 2
        print(ans)
Codeforces Round 1040 (Div. 2)
Contest Summary