@@ -39,42 +39,43 @@ Value compression is used to effectively handle large numbers.
39
39
40
40
``` cpp
41
41
42
- #include < bits/stdc++.h>
42
+ #include " bits/stdc++.h"
43
43
using namespace std ;
44
- const int MAX_NODES_GRAPH = 1e5 , MAX_NODES_TREE = 2e6 ;
45
- int nxt = 1 , timer = 0 , LOG ;
44
+ int timer = 0 ;
45
+ const int MAX_NODES_GRAPH = 1e5 ;
46
46
47
47
struct PersistentSegmentTree {
48
- int L [MAX_NODES_TREE + 1 ], R [MAX_NODES_TREE + 1 ], t [MAX_NODES_TREE + 1 ];
49
-
48
+ static const int MAX_NODES_TREE = 2e6 ;
49
+ int left_child [MAX_NODES_TREE + 1 ], right_child [MAX_NODES_TREE + 1 ], node_value [MAX_NODES_TREE + 1 ];
50
+ int nxt = 1 ;
50
51
/*
51
52
Updates the tree at a given position by incrementing the frequency of the specific
52
53
number added. It creates new nodes for every segment along the path from the root to
53
54
the target position, preserving the previous version of the tree while modifying
54
55
only the necessary parts.
55
56
*/
56
57
int update (int v , int l , int r , int pos ) {
57
- int nw = ++ nxt ; // Create a new node for the updated tree version
58
+ int new_node = ++ nxt ; // Create a new node for the updated tree version
58
59
59
60
if (l == r ) {
60
- t [ nw ] = t [v ] + 1 ; // At leaf, increment the value at position 'pos'
61
- return nw ;
61
+ node_value [ new_node ] = node_value [v ] + 1 ; // At leaf, increment the value at position 'pos'
62
+ return new_node ;
62
63
}
63
64
64
- L[ nw ] = L [v ]; // Copy left child from the previous version
65
- R[ nw ] = R [v ]; // Copy right child from the previous version
65
+ left_child[ new_node ] = left_child [v ]; // Copy left child from the previous version
66
+ right_child[ new_node ] = right_child [v ]; // Copy right child from the previous version
66
67
int m = (l + r) / 2;
67
68
68
69
// Update the left or right child based on the position
69
70
if (pos <= m) {
70
- L[ nw ] = update(L [v ], l, m, pos);
71
+ left_child[ new_node ] = update(left_child [v ], l, m, pos);
71
72
} else {
72
- R[ nw ] = update(R [v ], m + 1, r, pos);
73
+ right_child[ new_node ] = update(right_child [v ], m + 1, r, pos);
73
74
}
74
75
75
76
// Update the current node's value by combining the values of its children
76
- t[ nw ] = t[ L [ nw ]] + t[ R [ nw ]];
77
- return nw ;
77
+ node_value[ new_node ] = node_value[ left_child [ new_node ]] + node_value[ right_child [ new_node ]];
78
+ return new_node ;
78
79
}
79
80
80
81
// Queries kth smallest element between a and b
@@ -85,22 +86,22 @@ struct PersistentSegmentTree {
85
86
int m = (l + r) / 2;
86
87
87
88
// Calculate the number of elements in the left child of the current range
88
- int cnt = t[ L [a ]] + t[ L [b ]] - t[ L [anc ]] - t[ L [pr ]];
89
+ int leftSubtreeCount = node_value[ left_child [a ]] + node_value[ left_child [b ]] - node_value[ left_child [anc ]] - node_value[ left_child [pr ]];
89
90
90
- if (cnt >= k) {
91
- return query(L [a ], L [b ], L [anc ], L [pr ], l, m, k);
91
+ if (leftSubtreeCount >= k) {
92
+ return query(left_child [a ], left_child [b ], left_child [anc ], left_child [pr ], l, m, k);
92
93
} else {
93
- return query(R [a ], R [b ], R [anc ], R [pr ], m + 1, r, k - cnt );
94
+ return query(right_child [a ], right_child [b ], right_child [anc ], right_child [pr ], m + 1, r, k - leftSubtreeCount );
94
95
}
95
96
}
96
97
};
97
98
98
99
PersistentSegmentTree pst;
99
100
100
101
struct Graph {
101
- int roots[MAX_NODES_GRAPH + 1 ];
102
+ int LOG;
103
+ int roots[MAX_NODES_GRAPH + 1 ], tin[MAX_NODES_GRAPH + 1 ], tout[MAX_NODES_GRAPH + 1 ], val[MAX_NODES_GRAPH + 1 ];
102
104
vector<vector<int>> up;
103
- int tin[MAX_NODES_GRAPH + 1 ], tout[MAX_NODES_GRAPH + 1 ], val[MAX_NODES_GRAPH + 1 ];
104
105
vector<int> graph[MAX_NODES_GRAPH + 1 ];
105
106
106
107
void build(int n) {
0 commit comments