Buggy python submission (verdict: Time Limit Exceeded):
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]
    dct = {(a, b): i for i, (a, b) in enumerate(ab)}

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a == "B":
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct[("B", i)]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct[("W", j)]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()


Fixed submission:
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]
    dct = {(a, b): i for i, (a, b) in enumerate(ab)}

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a == "B":
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    for i in range(n+1):
        try:
            t = dct[("B", i)]
        except:
            pass
        for j in range(n+1):
            d = dp[i][j]
            try:
                dp[i+1][j] = min(dp[i+1][j], d+lb[t][i]+lw[t][j])
            except:
                pass
            try:
                t2 = dct[("W", j)]
                dp[i][j+1] = min(dp[i][j+1], d+lb[t2][i]+lw[t2][j])
            except:
                pass
    print(dp[n][n])


main()


Fixed submission:
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
    from sys import stdin
    input = stdin.readline

    # 一点更新・一点取得の加法BIT
    class BIT():
        def __init__(self, n):
            self.n = n
            self.bit = [0]*(n+1)

        # 位置iに値vを足す
        def add(self, i):
            x, n, bit = i+1, self.n, self.bit
            while x < n+1:
                bit[x] += 1
                x += x & (-x)

        # 位置0からiまでの和(sum(bit[:i]))を計算する
        def sum(self, i):
            ret, x, bit = 0, i, self.bit
            while x > 0:
                ret += bit[x]
                x -= x & (-x)
            return ret

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]

    f_B = [[0]*n for _ in [0]*(n+1)]  # f_B[i][j] = Bがi個、Wがj個あるときのBを置く手数
    f_W = [[0]*n for _ in [0]*(n+1)]  # f_W[i][j] = Bがi個、Wがj個あるときのWを置く手数
    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # まずf_Bから出す
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        f = f_B[i]
        for a, b in ab:
            if a == "B":
                f[b] = bit.sum(n-b-1)+cnt
                bit.add(n-b-1)
            else:
                if b >= i:
                    cnt += 1
    # f_Wも同様
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        f = f_W[i]
        for a, b in ab:
            if a == "W":
                f_W[i][b] = bit.sum(n-b-1)+cnt
                bit.add(n-b-1)
            else:
                if b >= i:
                    cnt += 1
    for i in range(n+1):
        for j in range(n+1):
            d = dp[i][j]
            try:
                dp[i+1][j] = min(dp[i+1][j], d+f_B[j][i])
            except:
                pass
            try:
                dp[i][j+1] = min(dp[i][j+1], d+f_W[i][j])
            except:
                pass
    print(dp[n][n])


main()


Fixed submission:
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
    from sys import stdin
    input = stdin.readline

    # 一点更新・一点取得の加法BIT
    class BIT():
        def __init__(self, n):
            self.n = n
            self.bit = [0]*(n+1)

        # 位置iに値vを足す
        def add(self, i):
            x, n, bit = i+1, self.n, self.bit
            while x < n+1:
                bit[x] += 1
                x += x & (-x)

        # 位置0からiまでの和(sum(bit[:i]))を計算する
        def sum(self, i):
            ret, x, bit = 0, i, self.bit
            while x > 0:
                ret += bit[x]
                x -= x & (-x)
            return ret

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]

    f_B = [[0]*(n+1) for _ in [0]*n]  # f_B[i][j] = Bがi個、Wがj個あるときのBを置く手数
    f_W = [[0]*(n+1) for _ in [0]*n]  # f_W[i][j] = Bがi個、Wがj個あるときのWを置く手数
    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # まずf_Bから出す
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        for a, b in ab:
            if a == "B":
                f_B[b][i] = bit.sum(n-b-1)+cnt
                bit.add(n-b-1)
            else:
                if b >= i:
                    cnt += 1
    # f_Wも同様
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        for a, b in ab:
            if a == "W":
                f_W[b][i] = bit.sum(n-b-1)+cnt
                bit.add(n-b-1)
            else:
                if b >= i:
                    cnt += 1
    for i in range(n+1):
        for j in range(n+1):
            d = dp[i][j]
            try:
                dp[i+1][j] = min(dp[i+1][j], d+f_B[i][j])
            except:
                pass
            try:
                dp[i][j+1] = min(dp[i][j+1], d+f_W[j][i])
            except:
                pass
    print(dp[n][n])


main()


Fixed submission:
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
    from sys import stdin
    input = stdin.readline

    # 一点更新・一点取得の加法BIT
    class BIT():
        def __init__(self, n):
            self.n = n
            self.maxbit = 2**(len(bin(n))-3)
            self.bit = [0]*(n+1)
            self.allsum = 0

        # 初期化する
        def make_bit(self, a):
            n, bit = self.n, self.bit
            for i, j in enumerate(a):
                x = i+1
                self.allsum += j
                while x < n+1:
                    bit[x] += j
                    x += x & (-x)

        # 位置iに値vを足す
        def add(self, i, v):
            x, n, bit = i+1, self.n, self.bit
            self.allsum += v
            while x < n+1:
                bit[x] += v
                x += x & (-x)

        # 位置0からiまでの和(sum(bit[:i]))を計算する
        def sum(self, i):
            ret, x, bit = 0, i, self.bit
            while x > 0:
                ret += bit[x]
                x -= x & (-x)
            return ret

        # 位置iからjまでの和(sum(bit[i:j]))を計算する
        def sum_range(self, i, j):
            return self.sum(j) - self.sum(i)

        # 和がw以上となる最小のインデックスを求める
        def lowerbound(self, w):
            if w <= 0:
                return 0
            x, k, n, bit = 0, self.maxbit, self.n, self.bit
            while k:
                if x+k <= n and bit[x+k] < w:
                    w -= bit[x+k]
                    x += k
                k //= 2
            return x

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]

    f_B = [[0]*(n+1) for _ in [0]*n]  # f_B[i][j] = Bがi個、Wがj個あるときのBを置く手数
    f_W = [[0]*(n+1) for _ in [0]*n]  # f_W[i][j] = Bがi個、Wがj個あるときのWを置く手数
    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # まずf_Bから出す
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        for a, b in ab:
            if a == "B":
                f_B[b][i] = bit.allsum-bit.sum(b)+cnt
                bit.add(b, 1)
            else:
                if b >= i:
                    cnt += 1
    # f_Wも同様
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        for a, b in ab:
            if a == "W":
                f_W[b][i] = bit.allsum-bit.sum(b)+cnt
                bit.add(b, 1)
            else:
                if b >= i:
                    cnt += 1
    for i in range(n+1):
        for j in range(n+1):
            d = dp[i][j]
            try:
                dp[i+1][j] = min(dp[i+1][j], d+f_B[i][j])
            except:
                pass
            try:
                dp[i][j+1] = min(dp[i][j+1], d+f_W[j][i])
            except:
                pass
    print(dp[n][n])


main()


Fixed submission:
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
    # 一点更新・一点取得の加法BIT
    class BIT():
        def __init__(self, n):
            self.n = n
            self.maxbit = 2**(len(bin(n))-3)
            self.bit = [0]*(n+1)
            self.allsum = 0

        # 初期化する
        def make_bit(self, a):
            n, bit = self.n, self.bit
            for i, j in enumerate(a):
                x = i+1
                self.allsum += j
                while x < n+1:
                    bit[x] += j
                    x += x & (-x)

        # 位置iに値vを足す
        def add(self, i, v):
            x, n, bit = i+1, self.n, self.bit
            self.allsum += v
            while x < n+1:
                bit[x] += v
                x += x & (-x)

        # 位置0からiまでの和(sum(bit[:i]))を計算する
        def sum(self, i):
            ret, x, bit = 0, i, self.bit
            while x > 0:
                ret += bit[x]
                x -= x & (-x)
            return ret

        # 位置iからjまでの和(sum(bit[i:j]))を計算する
        def sum_range(self, i, j):
            return self.sum(j) - self.sum(i)

        # 和がw以上となる最小のインデックスを求める
        def lowerbound(self, w):
            if w <= 0:
                return 0
            x, k, n, bit = 0, self.maxbit, self.n, self.bit
            while k:
                if x+k <= n and bit[x+k] < w:
                    w -= bit[x+k]
                    x += k
                k //= 2
            return x

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]

    f_B = [[10**9]*(n+1) for _ in [0]*n]  # f_B[i][j] = Bがi個、Wがj個あるときのBを置く手数
    f_W = [[10**9]*(n+1) for _ in [0]*n]  # f_W[i][j] = Bがi個、Wがj個あるときのWを置く手数
    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # まずf_Bから出す
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        for a, b in ab:
            if a == "B":
                f_B[b][i] = bit.allsum-bit.sum(b)+cnt
                bit.add(b, 1)
            else:
                if b >= i:
                    cnt += 1
    # f_Wも同様
    for i in range(n+1):
        bit = BIT(n)
        cnt = 0
        for a, b in ab:
            if a == "W":
                f_W[b][i] = bit.allsum-bit.sum(b)+cnt
                bit.add(b, 1)
            else:
                if b >= i:
                    cnt += 1
    for i in range(n+1):
        for j in range(n+1):
            d = dp[i][j]
            try:
                dp[i+1][j] = min(dp[i+1][j], d+f_B[i][j])
            except:
                pass
            try:
                dp[i][j+1] = min(dp[i][j+1], d+f_W[j][i])
            except:
                pass
    print(dp[n][n])


main()


Fixed submission:
def main():
    from sys import stdin
    input = stdin.readline

    n = int(input())
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print(dp[n][n])


main()