1
+
2
+ def rerooter (graph , default , combine , finalize = lambda nodeDP , node , eind : nodeDP ):
3
+ n = len (graph )
4
+ rootDP = [0 ] * n
5
+ forwardDP = [None ] * n
6
+ reverseDP = [None ] * n
7
+
8
+ def exclusive (A , zero , combine , node ):
9
+ n = len (A )
10
+ exclusiveA = [zero ] * n
11
+
12
+ for bit in range (n .bit_length ())[::- 1 ]:
13
+ for i in range (n )[::- 1 ]:
14
+ exclusiveA [i ] = exclusiveA [i // 2 ]
15
+ for i in range (n & (- 1 if bit else - 2 )):
16
+ ind = (i >> bit ) ^ 1
17
+ exclusiveA [ind ] = combine (exclusiveA [ind ], A [i ], node , i )
18
+ return exclusiveA
19
+
20
+ DP = [0 ] * n
21
+ bfs = [0 ]
22
+ P = [0 ] * n
23
+ for node in bfs :
24
+ for nei in graph [node ]:
25
+ if P [node ] != nei :
26
+ P [nei ] = node
27
+ bfs .append (nei )
28
+
29
+ for node in reversed (bfs ):
30
+ nodeDP = default [node ]
31
+ for eind , nei in enumerate (graph [node ]):
32
+ if P [node ] != nei :
33
+ nodeDP = combine (nodeDP , DP [nei ], node , eind )
34
+ DP [node ] = finalize (nodeDP , node , graph [node ].index (P [node ]) if node else - 1 )
35
+
36
+ for node in bfs :
37
+ DP [P [node ]] = DP [node ]
38
+ forwardDP [node ] = [DP [nei ] for nei in graph [node ]]
39
+ rerootDP = exclusive (forwardDP [node ], default [node ], combine , node )
40
+ reverseDP [node ] = [
41
+ finalize (nodeDP , node , eind ) for eind , nodeDP in enumerate (rerootDP )
42
+ ]
43
+ rootDP [node ] = finalize (
44
+ (
45
+ combine (rerootDP [0 ], forwardDP [node ][0 ], node , 0 )
46
+ if n > 1
47
+ else default [node ]
48
+ ),
49
+ node ,
50
+ - 1 ,
51
+ )
52
+ for nei , dp in zip (graph [node ], reverseDP [node ]):
53
+ DP [nei ] = dp
54
+ return rootDP , forwardDP , reverseDP
0 commit comments