88
99// Permutation tree
1010// Complexity: O(N log N)
11- // https://codeforces.com/blog/entry/78898 https://yukicoder.me/problems/no/1720
11+ // https://codeforces.com/blog/entry/78898 https://judge.yosupo.jp/problem/common_interval_decomposition_tree
1212struct permutation_tree {
1313 enum NodeType {
1414 JoinAsc,
@@ -17,13 +17,14 @@ struct permutation_tree {
1717 Leaf,
1818 None,
1919 };
20- struct node {
20+ struct Node {
2121 NodeType tp;
2222 int L, R; // i in [L, R)
2323 int mini, maxi; // A[i] in [mini, maxi]
24+ int par_id = -1 ;
2425 std::vector<int > child;
2526 int sz () const { return R - L; }
26- template <class OStream > friend OStream &operator <<(OStream &os, const node &n) {
27+ template <class OStream > friend OStream &operator <<(OStream &os, const Node &n) {
2728 os << " [[" << n.L << ' ,' << n.R << " )(ch:" ;
2829 for (auto i : n.child ) os << i << ' ,' ;
2930 return os << " )(tp=" << n.tp << " )]" ;
@@ -32,14 +33,14 @@ struct permutation_tree {
3233
3334 int root;
3435 std::vector<int > A;
35- std::vector<node > nodes;
36+ std::vector<Node > nodes;
3637
37- void _add_child (int parid , int chid) {
38- nodes[parid ].child .push_back (chid);
39- nodes[parid ].L = std::min (nodes[parid ].L , nodes[chid].L );
40- nodes[parid ].R = std::max (nodes[parid ].R , nodes[chid].R );
41- nodes[parid ].mini = std::min (nodes[parid ].mini , nodes[chid].mini );
42- nodes[parid ].maxi = std::max (nodes[parid ].maxi , nodes[chid].maxi );
38+ void _add_child (int par_id , int chid) {
39+ nodes[par_id ].child .push_back (chid);
40+ nodes[par_id ].L = std::min (nodes[par_id ].L , nodes[chid].L );
41+ nodes[par_id ].R = std::max (nodes[par_id ].R , nodes[chid].R );
42+ nodes[par_id ].mini = std::min (nodes[par_id ].mini , nodes[chid].mini );
43+ nodes[par_id ].maxi = std::max (nodes[par_id ].maxi , nodes[chid].maxi );
4344 }
4445
4546 permutation_tree () : root(-1 ) {}
@@ -62,15 +63,15 @@ struct permutation_tree {
6263 lo.push_back (i);
6364
6465 int h = nodes.size ();
65- nodes.push_back ({NodeType::Leaf, i, i + 1 , A[i], A[i], std::vector<int >{}});
66+ nodes.push_back ({NodeType::Leaf, i, i + 1 , A[i], A[i], - 1 , std::vector<int >{}});
6667
6768 while (true ) {
6869 NodeType join_tp = NodeType::None;
6970 if (!st.empty () and nodes[st.back ()].maxi + 1 == nodes[h].mini ) join_tp = JoinAsc;
7071 if (!st.empty () and nodes[h].maxi + 1 == nodes[st.back ()].mini ) join_tp = JoinDesc;
7172
7273 if (!st.empty () and join_tp != NodeType::None) {
73- const node &vtp = nodes[st.back ()];
74+ const Node &vtp = nodes[st.back ()];
7475 // Insert v as the child of the top node in the stack
7576 if (join_tp == vtp.tp ) {
7677 // Append child to existing Join node
@@ -81,15 +82,15 @@ struct permutation_tree {
8182 // Make new join node (with exactly two children)
8283 int j = st.back ();
8384 nodes.push_back (
84- {join_tp, nodes[j].L , nodes[j].R , nodes[j].mini , nodes[j].maxi , {j}});
85+ {join_tp, nodes[j].L , nodes[j].R , nodes[j].mini , nodes[j].maxi , - 1 , {j}});
8586 st.pop_back ();
8687 _add_child (nodes.size () - 1 , h);
8788 h = nodes.size () - 1 ;
8889 }
8990 } else if (seg.prod (0 , i + 1 - nodes[h].sz ()) == 0 ) {
9091 // Make Cut node
9192 int L = nodes[h].L , R = nodes[h].R , maxi = nodes[h].maxi , mini = nodes[h].mini ;
92- nodes.push_back ({NodeType::Cut, L, R, mini, maxi, {h}});
93+ nodes.push_back ({NodeType::Cut, L, R, mini, maxi, - 1 , {h}});
9394 h = nodes.size () - 1 ;
9495 do {
9596 _add_child (h, st.back ());
@@ -104,6 +105,11 @@ struct permutation_tree {
104105 seg.add (0 , i + 1 , -1 );
105106 }
106107 assert (st.size () == 1 );
108+
109+ for (int i = 0 ; i < int (nodes.size ()); i++) {
110+ for (auto ch : nodes[i].child ) nodes[ch].par_id = i;
111+ }
112+
107113 root = st[0 ];
108114 }
109115
0 commit comments