ivolff

LabASD ST I

Apr 21st, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.57 KB | None | 0 0
  1. #include <iostream>
  2. #include <limits>
  3. #include <vector>
  4. #include <deque>
  5.  
  6. using namespace std;
  7.  
  8. typedef long long type;
  9.  
  10. const type zero = numeric_limits<type>::max();
  11. int size;
  12.  
  13. struct border {
  14.     int left;
  15.     int right;
  16.  
  17.     border(int left, int right);
  18.  
  19.     operator bool() const;
  20.  
  21.     inline int mid() const;
  22.     inline int length() const;
  23.  
  24.     bool in(const border& other) const;
  25.     bool out(const border& other) const;
  26. };
  27.  
  28. struct node {
  29. private:
  30.     node* left = nullptr;
  31.     node* right = nullptr;
  32.  
  33. public:
  34.     border section;
  35.  
  36.     type sum = 0;
  37.     type new_value = zero;
  38.     type max_height = 0;
  39.  
  40.     node() = default;
  41.     explicit node(const border& section);
  42.     node(int left, int right);
  43.     ~node();
  44.  
  45.     void push();
  46.     int query(int height);
  47.     void set(border request, int value);
  48. };
  49.  
  50. node* root = nullptr;
  51.  
  52. int main() {
  53.     ios_base::sync_with_stdio(false);
  54.     cin >> size;
  55.  
  56.     root = new node(0, size - 1);
  57.  
  58.     char command;
  59.     int left_border, right_border;
  60.     int value;
  61.     int height;
  62.  
  63.     while (cin >> command) {
  64.         switch (command) {
  65.             case 'I':
  66.                 cin >> left_border >> right_border >> value;
  67.                 root->set(border(left_border - 1, right_border - 1), value);
  68.                 break;
  69.             case 'Q':
  70.                 cin >> height;
  71.                 cout << root->query(height) << endl;
  72.                 break;
  73.             case 'E':
  74.                 delete root;
  75.                 return 0;
  76.         }
  77.     }
  78.  
  79.     delete root;
  80.     return 0;
  81. }
  82.  
  83. border::border(int left, int right) : left(left), right(right) {}
  84.  
  85. border::operator bool() const {
  86.     return left != right;
  87. }
  88.  
  89. inline int border::mid() const {
  90.     return left + (right - left) / 2;
  91. }
  92.  
  93. inline int border::length() const {
  94.     return right - left + 1;
  95. }
  96.  
  97. bool border::in(const border& other) const {
  98.     return other.left <= left && right <= other.right;
  99. }
  100.  
  101. bool border::out(const border& other) const {
  102.     return other.right < left || right < other.left;
  103. }
  104.  
  105. node::node(const border& section) : section(section) {}
  106.  
  107. node::node(int left, int right) : section(left, right) {}
  108.  
  109. node::~node() {
  110.     if (left) {
  111.         delete left;
  112.     }
  113.  
  114.     if (right) {
  115.         delete right;
  116.     }
  117. }
  118.  
  119. void node::push() {
  120.     if (section) {
  121.         if (!left) {
  122.             left = new node(border(section.left, section.mid()));
  123.         }
  124.  
  125.         if (!right) {
  126.             right = new node(border(section.mid() + 1, section.right));
  127.         }
  128.     }
  129.  
  130.     if (new_value != zero) {
  131.         sum = new_value * section.length();
  132.         max_height = sum;
  133.  
  134.         if (section) {
  135.             left->new_value = new_value;
  136.             right->new_value = new_value;
  137.         }
  138.  
  139.         new_value = zero;
  140.     }
  141. }
  142.  
  143. int node::query(int height) {
  144.     push();
  145.  
  146.     if (max_height <= height) {
  147.         return section.length();
  148.     }
  149.  
  150.     if (!section) {
  151.         return 0;
  152.     }
  153.  
  154.     left->push();
  155.     if (left->max_height > height) {
  156.         return left->query(height);
  157.     }
  158.  
  159.     return left->section.length() + right->query(height - (int) left->sum);
  160. }
  161.  
  162. void node::set(border request, int value) {
  163.     push();
  164.  
  165.     if (section.out(request)) {
  166.         return;
  167.     }
  168.  
  169.     if (section.in(request)) {
  170.         new_value = value;
  171.         push();
  172.         return;
  173.     }
  174.  
  175.     left->set(request, value);
  176.     right->set(request, value);
  177.  
  178.     sum = left->sum + right->sum;
  179.     max_height = max(left->max_height, left->sum + right->max_height);
  180. }
Advertisement
Add Comment
Please, Sign In to add comment