Advertisement
SansPapyrus683

Bad Solution for "Mountains"

Mar 26th, 2023
911
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.00 KB | Source Code | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4.  
  5. using std::cout;
  6. using std::endl;
  7. using std::vector;
  8. using ld = long double;
  9.  
  10. /** @brief range update, range query segtree */
  11. template <typename T>
  12. class RURQSegtree {
  13.     private:
  14.         const T NO_OP = -INT32_MIN;
  15.  
  16.         int len;
  17.         vector<T> vals;
  18.         vector<T> ops;
  19.  
  20.         T calc_op(T a, T b) {
  21.             return a + b;
  22.         }
  23.  
  24.         void mod_val(T& a, T b, T len) {
  25.             a = b == NO_OP ? a : b * len;
  26.         }
  27.  
  28.         void propagate(int at, int left, int right) {
  29.             if (right - left == 1) {
  30.                 return;
  31.             }
  32.             int mid = (left + right) / 2;
  33.             mod_val(vals[2 * at + 1], ops[at], mid - left);
  34.             mod_val(ops[2 * at + 1], ops[at], 1);
  35.             mod_val(vals[2 * at + 2], ops[at], right - mid);
  36.             mod_val(ops[2 * at + 2], ops[at], 1);
  37.             ops[at] = NO_OP;
  38.         }
  39.  
  40.         void set_range(int start, int end, T val, int at, int left, int right) {
  41.             propagate(at, left, right);
  42.             if (left >= end || start >= right) {
  43.                 return;
  44.             }
  45.             if (start <= left && right <= end) {
  46.                 mod_val(vals[at], val, right - left);
  47.                 mod_val(ops[at], val, 1);
  48.                 return;
  49.             }
  50.             int mid = (left + right) / 2;
  51.             set_range(start, end, val, 2 * at + 1, left, mid);
  52.             set_range(start, end, val, 2 * at + 2, mid, right);
  53.             vals[at] = calc_op(vals[2 * at + 1], vals[2 * at + 2]);
  54.             mod_val(vals[at], ops[at], right - left);
  55.         }
  56.  
  57.         T sum_range(int start, int end, int at, int left, int right) {
  58.             propagate(at, left, right);
  59.             if (left >= end || start >= right) {
  60.                 return 0;
  61.             }
  62.             if (start <= left && right <= end) {
  63.                 return vals[at];
  64.             }
  65.             int mid = (left + right) / 2;
  66.             T left_res = sum_range(start, end, 2 * at + 1, left, mid);
  67.             T right_res = sum_range(start, end, 2 * at + 2, mid, right);
  68.             T ret = calc_op(left_res, right_res);
  69.             mod_val(ret, ops[at], std::min(end, right) - std::max(start, left));
  70.             return ret;
  71.         }
  72.     public:
  73.         RURQSegtree(int len) {
  74.             int actual_len = 1;
  75.             while (actual_len < len) {
  76.                 actual_len *= 2;
  77.             }
  78.             this->len = actual_len;
  79.             vals = vector<T>(2 * actual_len);
  80.             ops = vector<T>(2 * actual_len);
  81.         }
  82.  
  83.         /** @brief sets all elements in [start, end) to val */
  84.         void set_range(int start, int end, T val) {
  85.             set_range(start, end, val, 0, 0, len);
  86.         }
  87.  
  88.         /** @return the sum of all values in the range [start, end) */
  89.         T sum_range(int start, int end) {
  90.             return sum_range(start, end, 0, 0, len);
  91.         }
  92. };
  93.  
  94. /**
  95.  * 2022 dec gold
  96.  * 5
  97.  * 2 4 3 1 5
  98.  * 3
  99.  * 4 3
  100.  * 1 3
  101.  * 3 2 should output 7, 10, and 7, each on a new line
  102.  */
  103. int main() {
  104.     std::ios::sync_with_stdio(false);
  105.     std::cin.tie(NULL);
  106.  
  107.     int mountain_num;
  108.     std::cin >> mountain_num;
  109.     vector<int> heights(mountain_num);
  110.     for (int& m : heights) {
  111.         std::cin >> m;
  112.     }
  113.    
  114.     vector<RURQSegtree<ld>> mtns1;
  115.     vector<RURQSegtree<int>> mtns2;
  116.     long long viewable_pairs = 0;
  117.     for (int m = 0; m < mountain_num; m++) {
  118.         mtns1.push_back(RURQSegtree<ld>(mountain_num));
  119.         mtns2.push_back(RURQSegtree<int>(mountain_num));
  120.         ld curr_max = INT64_MIN;
  121.         int last = 0;
  122.         for (int other = m + 1; other < mountain_num; other++) {
  123.             ld slope = (ld) (heights[other] - heights[m]) / (other - m);
  124.             if (slope >= curr_max) {
  125.                 mtns1[m].set_range(last, other, curr_max);
  126.                 mtns2[m].set_range(other, other + 1, 1);
  127.                 curr_max = slope;
  128.                 viewable_pairs++;
  129.                 last = other;
  130.             }
  131.         }
  132.         mtns1[m].set_range(last, mountain_num, curr_max);
  133.     }
  134.  
  135.     cout << "done" << endl;
  136.  
  137.     int query_num;
  138.     std::cin >> query_num;
  139.     for (int q = 0; q < query_num; q++) {
  140.         int pos, inc;
  141.         std::cin >> pos >> inc;
  142.         pos--;
  143.         heights[pos] += inc;
  144.         for (int m = 0; m < pos; m++) {
  145.             ld slope = (ld) (heights[pos] - heights[m]) / (pos - m);
  146.             if (slope < mtns1[m].sum_range(pos, pos + 1)) {
  147.                 continue;
  148.             }
  149.            
  150.             int lo = pos;
  151.             int hi = mountain_num;
  152.             while (lo <= hi) {
  153.                 int mid = (lo + hi) / 2;
  154.                 float cmp_slope = mtns1[m].sum_range(mid, mid + 1);
  155.                 if (cmp_slope > slope) {
  156.                     hi = mid - 1;
  157.                 } else if (cmp_slope == slope) {
  158.                     if (mid < pos) {
  159.                         lo = mid + 1;
  160.                     } else {
  161.                         hi = mid - 1;
  162.                     }
  163.                 } else {
  164.                     lo = mid + 1;
  165.                 }
  166.             }
  167.             mtns1[m].set_range(pos, lo, slope);
  168.             viewable_pairs -= mtns2[m].sum_range(pos, lo) - 1;
  169.             mtns2[m].set_range(pos, lo, 0);
  170.             mtns2[m].set_range(pos, pos + 1, 1);
  171.         }
  172.  
  173.         ld curr_max = INT64_MIN;
  174.         viewable_pairs -= mtns2[pos].sum_range(0, mountain_num);
  175.         int last = 0;
  176.         for (int m = pos + 1; m < mountain_num; m++) {
  177.             ld slope = (ld) (heights[m] - heights[pos]) / (m - pos);
  178.             if (slope >= curr_max) {
  179.                 mtns1[pos].set_range(last, m, curr_max);  
  180.                 mtns2[pos].set_range(m, m + 1, 1);
  181.                 curr_max = slope;
  182.                 last = m;
  183.             }
  184.         }
  185.         mtns1[pos].set_range(last, mountain_num, curr_max);
  186.         viewable_pairs += mtns2[pos].sum_range(0, mountain_num);
  187.  
  188.         cout << viewable_pairs << '\n';
  189.     }
  190. }
  191.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement