Example #1
0
    def test_path_sum(self):
        root = PathSumNode("root", 1 << 0)
        c1 = PathSumNode("c1", 1 << 1)
        c2 = PathSumNode("c2", 1 << 2)
        c3 = PathSumNode("c3", 1 << 6)

        c1_1 = PathSumNode("c1_1", 1 << 3)

        c2_1 = PathSumNode("c2_1", 1 << 4)
        c2_2 = PathSumNode("c2_2", 1 << 5)

        c2_2_1 = PathSumNode("c2_2_1", 1 << 6)

        build_link_cut_tree((
            root,
            [
                (c1, [
                    (c1_1, []),
                ]),
                (c2, [
                    (c2_1, []),
                    (c2_2, [
                        (c2_2_1, []),
                    ]),
                ]),
                (c3, []),
            ],
        ))

        self.assertEqual(root.lc_path_aggregate(), root.value)
        self.assertEqual(c1.lc_path_aggregate(), root.value + c1.value)
        self.assertEqual(c2.lc_path_aggregate(), root.value + c2.value)
        self.assertEqual(c3.lc_path_aggregate(), root.value + c3.value)

        self.assertEqual(c1_1.lc_path_aggregate(),
                         root.value + c1.value + c1_1.value)
        self.assertEqual(c2_1.lc_path_aggregate(),
                         root.value + c2.value + c2_1.value)
        self.assertEqual(c2_2.lc_path_aggregate(),
                         root.value + c2.value + c2_2.value)
        self.assertEqual(
            c2_2_1.lc_path_aggregate(),
            root.value + c2.value + c2_2.value + c2_2_1.value,
        )

        self.assertEqual(c2_2.lc_get_root(), root)

        c2_2.lc_cut()
        self.assertEqual(c2_2_1.lc_path_aggregate(), c2_2.value + c2_2_1.value)
        self.assertEqual(c2_2.lc_path_aggregate(), c2_2.value)
        self.assertEqual(c2_2_1.lc_get_root(), c2_2)

        root.lc_link(c2_2)
        self.assertEqual(root.lc_path_aggregate(), c2_2.value + root.value)
        self.assertEqual(c3.lc_path_aggregate(),
                         c2_2.value + root.value + c3.value)
        self.assertEqual(c1_1.lc_path_aggregate(),
                         c2_2.value + root.value + c1.value + c1_1.value)
        self.assertEqual(root.lc_get_root(), c2_2)
        self.assertEqual(c1_1.lc_get_root(), c2_2)
Example #2
0
    def test_subtree_sum(self):
        nodes = {}
        for i, c in enumerate("ABCDEFG"):
            nodes[c] = SubtreeSumNode(c, 1 << i)

        build_link_cut_tree(
            (
                nodes["A"],
                [
                    (nodes["B"], [(nodes["D"], []), (nodes["E"], []),]),
                    (nodes["C"], [(nodes["F"], []), (nodes["G"], []),]),
                ],
            )
        )

        sums = {
            "A": (1 << 7) - 1,
            "B": 0b11010,
            "C": 0b1100100,
            "D": 1 << 3,
            "E": 1 << 4,
            "F": 1 << 5,
            "G": 1 << 6,
        }

        for name, node in nodes.items():
            self.assertEqual(node.get_sum(), sums[name])

        nodes["C"].lc_cut()
        diffs = {
            "A": -sums["C"],
        }
        for name, node in nodes.items():
            self.assertEqual(node.get_sum(), sums[name] + diffs.get(name, 0), f"{name}")

        nodes["C"].lc_link(nodes["E"])
        diffs = {
            "B": sums["C"],
            "E": sums["C"],
        }
        for name, node in nodes.items():
            self.assertEqual(node.get_sum(), sums[name] + diffs.get(name, 0), f"{name}")

        nodes["C"].set_value(nodes["C"].value + (1 << 8))
        diffs = {
            "A": 1 << 8,
            "B": sums["C"] + (1 << 8),
            "E": sums["C"] + (1 << 8),
            "C": 1 << 8,
        }
        for name, node in nodes.items():
            self.assertEqual(node.get_sum(), sums[name] + diffs.get(name, 0), f"{name}")
Example #3
0
    def test_lca(self):
        nodes = {}
        for c in map(chr, range(ord("a"), ord("l") + 1)):
            nodes[c] = Node(c)

        build_link_cut_tree((
            nodes["a"],
            [
                (
                    nodes["b"],
                    [
                        (nodes["e"], [
                            (nodes["h"], []),
                        ]),
                        (nodes["f"], []),
                    ],
                ),
                (nodes["c"], []),
                (
                    nodes["d"],
                    [
                        (
                            nodes["g"],
                            [
                                (nodes["i"], []),
                                (nodes["j"], [
                                    (nodes["l"], []),
                                ]),
                                (nodes["k"], []),
                            ],
                        ),
                    ],
                ),
            ],
        ))

        self.assertEqual(nodes["a"].lc_lca(nodes["f"]), nodes["a"])
        self.assertEqual(nodes["f"].lc_lca(nodes["a"]), nodes["a"])
        self.assertEqual(nodes["j"].lc_lca(nodes["i"]), nodes["g"])
        self.assertEqual(nodes["h"].lc_lca(nodes["k"]), nodes["a"])
        self.assertEqual(nodes["h"].lc_lca(nodes["f"]), nodes["b"])
Example #4
0
    def test_evert(self):
        nodes = {}
        for c in map(chr, range(ord("a"), ord("l") + 1)):
            nodes[c] = PathSumNode(c, 1)

        build_link_cut_tree((
            nodes["a"],
            [
                (
                    nodes["b"],
                    [
                        (nodes["e"], [
                            (nodes["h"], []),
                        ]),
                        (nodes["f"], []),
                    ],
                ),
                (nodes["c"], []),
                (
                    nodes["d"],
                    [
                        (
                            nodes["g"],
                            [
                                (nodes["i"], []),
                                (nodes["j"], [
                                    (nodes["l"], []),
                                ]),
                                (nodes["k"], []),
                            ],
                        ),
                    ],
                ),
            ],
        ))

        nodes["j"].lc_evert()

        self.assertEqual(nodes["l"].lc_path_aggregate(), 2)
        self.assertEqual(nodes["h"].lc_path_aggregate(), 7)
Example #5
0
    def test_pointers(self):
        nodes = {}
        for c in "ABCDEFG":
            nodes[c] = PointerNode(c)

        build_link_cut_tree((
            nodes["A"],
            [
                (nodes["B"], [
                    (nodes["D"], []),
                    (nodes["E"], []),
                ]),
                (nodes["C"], [
                    (nodes["F"], []),
                    (nodes["G"], []),
                ]),
            ],
        ))

        assert nodes["A"].lc_parent == None

        assert nodes["A"].lc_children == {nodes["B"], nodes["C"]}
        assert nodes["B"].lc_parent == nodes["A"]
        assert nodes["C"].lc_parent == nodes["A"]

        assert nodes["B"].lc_children == {nodes["D"], nodes["E"]}
        assert nodes["D"].lc_parent == nodes["B"]
        assert nodes["E"].lc_parent == nodes["B"]

        assert nodes["C"].lc_children == {nodes["F"], nodes["G"]}
        assert nodes["F"].lc_parent == nodes["C"]
        assert nodes["G"].lc_parent == nodes["C"]

        assert nodes["D"].lc_children == set()
        assert nodes["E"].lc_children == set()
        assert nodes["F"].lc_children == set()
        assert nodes["G"].lc_children == set()