Advertisement
TAImatem

Решение RMQ из тренировки на ДО

Jan 13th, 2023
1,101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.26 KB | None | 0 0
  1. vector<int> f;
  2. void f_inc(int i, int d)
  3. {
  4.     while (i < f.size())
  5.     {
  6.         f[i] += d;
  7.         i = i | (i + 1);
  8.     }
  9. }
  10. int f_get(int i)
  11. {
  12.     int sum = 0;
  13.     while (i >= 0)
  14.     {
  15.         sum += f[i];
  16.         i = (i & (i + 1)) - 1;
  17.     }
  18.     return sum;
  19. }
  20.  
  21. int find_f_pos(int a)
  22. {
  23.     int i = 0;
  24.     while ((1 << i) < f.size()) i++;
  25.     int l = 0;
  26.     while (i > 0)
  27.     {
  28.         i--;
  29.         int m = l + (1 << i) - 1;
  30.         if (m >= f.size())
  31.             continue;
  32.         if (f[m] < a)
  33.         {
  34.             a -= f[m];
  35.             l = m + 1;
  36.         }
  37.     }
  38.     return l;
  39. }
  40.  
  41. vector<int> min_do;
  42. void do_set(int i, int a, int d = 1, int lf = 0, int rf = f.size() - 1)
  43. {
  44.     if (lf == rf)
  45.     {
  46.         min_do[d] = a;
  47.         return;
  48.     }
  49.     int m = (lf + rf) / 2;
  50.     if (i <= m)
  51.         do_set(i, a, d * 2, lf, m);
  52.     else
  53.         do_set(i, a, d * 2 + 1, m + 1, rf);
  54.     min_do[d] = min(min_do[d * 2], min_do[d * 2 + 1]);
  55. }
  56. int do_get(int l, int r, int d = 1, int lf = 0, int rf = f.size() - 1)
  57. {
  58.     if (lf == l && rf == r)
  59.     {
  60.         return min_do[d];
  61.     }
  62.     int m = (lf + rf) / 2;
  63.     if (r <= m)
  64.         return do_get(l, r, d * 2, lf, m);
  65.     if (l > m)
  66.         return do_get(l, r, d * 2 + 1, m + 1, rf);
  67.     return min(do_get(l, m, d * 2, lf, m), do_get(m + 1, r, d * 2 + 1, m + 1, rf));
  68. }
  69.  
  70. int main() {
  71. //#ifndef DEBUG
  72.     freopen("rmq.in", "r", stdin);
  73.     freopen("rmq.out", "w", stdout);
  74. //#endif
  75.     ifstream fin("rmq.in");
  76.     ofstream fout("rmq.out");
  77.     int n;
  78.     fin >> n;
  79.     vector<pair<bool, pair<int, int>>> req(n);
  80.     int sz = 0;
  81.     for (auto&r:req)
  82.     {
  83.         char c;
  84.         while ((c = fin.get()) < 43);
  85.         fin >> r.second.first >> r.second.second;
  86.         r.first = c == '?';
  87.         sz += c == '+';
  88.     }
  89.  
  90.     f.resize(sz, 0);
  91.     for (int i = 0; i < sz; i++)
  92.         f_inc(i, 1);
  93.     for (int i = n - 1; i >= 0; i--)
  94.     {
  95.         if (req[i].first)
  96.         {
  97.             int p = find_f_pos(req[i].second.first);
  98.             req[i].second.first = p;
  99.             p = find_f_pos(req[i].second.second);
  100.             req[i].second.second = p;
  101.         }
  102.         else
  103.         {
  104.             int p = find_f_pos(req[i].second.first + 1);
  105.             req[i].second.first = p;
  106.             f_inc(p, -1);
  107.         }
  108.     }
  109.  
  110.     min_do.resize(sz * 4, INT32_MAX);
  111.     for (int i = 0; i < n; i++)
  112.     {
  113.         if (req[i].first)
  114.         {
  115.             int l = req[i].second.first;
  116.             int r = req[i].second.second;
  117.             fout << do_get(l, r) << '\n';
  118.         }
  119.         else
  120.         {
  121.             int p = req[i].second.first;
  122.             f_inc(p, 1);
  123.             do_set(p, req[i].second.second);
  124.         }
  125.     }
  126.     fout.flush();
  127.     return 0;
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement