2022-04-16 09:24:00 +02:00
|
|
|
//
|
|
|
|
// Created by maximilian on 16.04.22.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include<vector>
|
|
|
|
#include "geometry.h"
|
|
|
|
|
|
|
|
#ifndef PROG_SEGMENT_TREE_H
|
|
|
|
#define PROG_SEGMENT_TREE_H
|
|
|
|
|
|
|
|
|
2022-04-16 11:34:29 +02:00
|
|
|
struct TreeNode {
|
|
|
|
unsigned coverage;
|
|
|
|
Coordinate left_coord;
|
|
|
|
Coordinate right_coord;
|
|
|
|
inline Unit segment_length();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-04-16 09:24:00 +02:00
|
|
|
class SegmentTree {
|
2022-04-16 11:34:29 +02:00
|
|
|
std::vector<TreeNode> _nodes;
|
|
|
|
Unit _covered_cross_section_length;
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param coords Sorted vector of coordinates
|
|
|
|
*/
|
|
|
|
SegmentTree(const std::vector<RectCoord>& coords);
|
2022-04-16 09:24:00 +02:00
|
|
|
|
2022-04-16 11:34:29 +02:00
|
|
|
inline Unit length_covered_intervals();
|
|
|
|
inline void add_interval(Interval interval);
|
|
|
|
inline void remove_interval(Interval interval);
|
|
|
|
|
|
|
|
private:
|
|
|
|
inline static Index left_child_idx(Index node_idx);
|
|
|
|
inline static Index right_child_idx(Index node_idx);
|
|
|
|
inline TreeNode& left_child(Index node_idx);
|
|
|
|
inline TreeNode& right_child(Index node_idx);
|
|
|
|
inline void update_added(Index node_idx);
|
|
|
|
inline void update_removed(Index node_idx);
|
|
|
|
void add_interval(Interval interval, Index node_idx);
|
|
|
|
void remove_interval(Interval interval, Index node_idx);
|
2022-04-16 09:24:00 +02:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2022-04-16 11:34:29 +02:00
|
|
|
/*****************************************************
|
|
|
|
* INLINE section
|
|
|
|
****************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TreeNode& SegmentTree::left_child(Index node_idx) {
|
|
|
|
return _nodes[left_child_idx(node_idx)];
|
|
|
|
}
|
|
|
|
|
|
|
|
TreeNode& SegmentTree::right_child(Index node_idx) {
|
|
|
|
return _nodes[right_child_idx(node_idx)];
|
|
|
|
}
|
|
|
|
|
|
|
|
Unit SegmentTree::length_covered_intervals() {
|
|
|
|
return _covered_cross_section_length;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SegmentTree::add_interval(Interval interval) {
|
|
|
|
add_interval(interval, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SegmentTree::remove_interval(Interval interval) {
|
|
|
|
remove_interval(interval, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SegmentTree::update_added(Index node_idx) {
|
|
|
|
++(_nodes[node_idx].coverage);
|
|
|
|
if(_nodes[node_idx].coverage == 1) {
|
|
|
|
_covered_cross_section_length += _nodes[node_idx].segment_length();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SegmentTree::update_removed(Index node_idx) {
|
|
|
|
--(_nodes[node_idx].coverage);
|
|
|
|
if(_nodes[node_idx].coverage == 0) {
|
|
|
|
_covered_cross_section_length -= _nodes[node_idx].segment_length();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Index SegmentTree::left_child_idx(Index node_idx) {
|
|
|
|
return 2*node_idx + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Index SegmentTree::right_child_idx(Index node_idx) {
|
|
|
|
return 2*node_idx + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Unit TreeNode::segment_length() {
|
|
|
|
return right_coord - left_coord;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-04-16 09:24:00 +02:00
|
|
|
#endif //PROG_SEGMENT_TREE_H
|