Advertisement
Guest User

Untitled

a guest
Nov 18th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.12 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #pragma GCC optimize ("O3")
  3. #pragma GCC optimize ("unroll-loops")
  4. #include <bits/stdc++.h>
  5. using ll = long long;
  6. #define DEBUG cout << "DEBUG\n";
  7. #define eb emplace_back
  8. #define em emplace
  9. #define pii pair<int, int>
  10. typedef long double ld;
  11. using namespace std;
  12. const ld PI = 3.14159265358979323L;
  13.  
  14. const int N = 5e5 + 7;
  15. mt19937 rnd(time(0));
  16.  
  17. struct Treap {
  18.     int nextInd, value, minValue;
  19.     int y = rnd();
  20.     Treap *l = nullptr;
  21.     Treap *r = nullptr;
  22.     Treap *p = nullptr;
  23.     Treap(int value, int nextInd) : nextInd(nextInd), value(value), minValue(value) {}
  24. };
  25.  
  26. int minValue(Treap *t) {
  27.     if (t == nullptr) {
  28.         return INT_MAX;
  29.     }
  30.     return t->minValue;
  31. }
  32.  
  33. void update(Treap *t) {
  34.     if (t == nullptr) {
  35.         return;
  36.     }
  37.     t->minValue = min({minValue(t->r), minValue(t->l), t->value});
  38. }
  39.  
  40. pair<Treap*, Treap*> split(Treap *t, int k) {
  41.     if (t == nullptr) {
  42.         return { nullptr, nullptr };
  43.     }
  44.     if (t->nextInd <= k) {
  45.         auto q = split(t->r, k);
  46.         t->r = q.first;
  47.         update(t);
  48.         return { t, q.second };
  49.     }
  50.     auto q = split(t->l, k);
  51.     t->l = q.second;
  52.     update(t);
  53.     return { q.first, t };
  54. }
  55.  
  56. Treap* merge(Treap *l, Treap *r) {
  57.     if (l == nullptr) {
  58.         return r;
  59.     }
  60.     if (r == nullptr) {
  61.         return l;
  62.     }
  63.     if (l->y > r->y) {
  64.         l->r = merge(l->r, r);
  65.         update(l);
  66.         return l;
  67.     }
  68.     r->l = merge(l, r->l);
  69.     update(r);
  70.     return r;
  71. }
  72.  
  73. Treap* erase(Treap *t, int k) {
  74.     if (t == nullptr) {
  75.         return nullptr;
  76.     }
  77.     if (t->nextInd == k) {
  78.         return merge(t->l, t->r);
  79.     }
  80.     if (t->nextInd > k) {
  81.         t->l = erase(t->l, k);
  82.     }
  83.     else {
  84.         t->r = erase(t->r, k);
  85.     }
  86.     update(t);
  87.     return t;
  88. }
  89.  
  90. Treap* add(Treap *t, Treap *toAdd) {
  91.     auto q = split(t, toAdd->nextInd);
  92.     t = merge(q.first, toAdd);
  93.     t = merge(t, q.second);
  94.     return t;
  95. }
  96.  
  97. int n, m;
  98. Treap *fenv[N], *lastTreap[N];
  99. tuple<int, int, int> preBuild[3 * N];
  100.  
  101. void erase(int v, int toErase) {
  102.     for (; v <= n; v |= v + 1) {
  103.         fenv[v] = erase(fenv[v], toErase);
  104.     }
  105. }
  106.  
  107. void add(int v, int value, int nextInd) {
  108.     for (; v <= n; v |= v + 1) {
  109.         fenv[v] = add(fenv[v], new Treap(value, nextInd));
  110.     }
  111. }
  112.  
  113. int get(int v, int r) {
  114.     v--;
  115.     int ans = INT_MAX;
  116.     for (; v >= 0; v = (v & (v + 1)) - 1) {
  117.         auto q = split(fenv[v], r);
  118.         ans = min(ans, minValue(q.second));
  119.         fenv[v] = merge(q.first, q.second);
  120.     }
  121.     return ans;
  122. }
  123.  
  124. void build(int v, int value, int nextInd) {
  125.     for (; v <= n; v |= v + 1) {
  126.         Treap *t = lastTreap[v];
  127.         Treap *toAdd = new Treap(value, nextInd);
  128.         lastTreap[v] = toAdd;
  129.         if (t == nullptr) {
  130.             fenv[v] = toAdd;
  131.             continue;
  132.         }
  133.         if (t->y > toAdd->y) {
  134.             t->r = toAdd;
  135.             toAdd->p = t;
  136.             update(t);
  137.             continue;
  138.         }
  139.         while (t->p != nullptr && t->p->y < toAdd->y) {
  140.             t = t->p;
  141.         }
  142.         if (t->p == nullptr) {
  143.             toAdd->l = t;  
  144.             fenv[v] = toAdd;
  145.             update(toAdd);
  146.         }
  147.         else {
  148.             toAdd->l = t;
  149.             t->p->r = toAdd;
  150.             toAdd->p = t->p;
  151.             update(toAdd);
  152.             update(toAdd->p);
  153.         }
  154.     }
  155. }
  156.  
  157. set<int> nums[N];
  158. int arr[N];
  159.  
  160. int main() {
  161.  
  162.     ios_base::sync_with_stdio(0);
  163.     cin.tie(0);
  164.     cout.tie(0);
  165. #ifdef _DEBUG
  166.     freopen("input.txt", "r", stdin);
  167.     freopen("output.txt", "w", stdout);
  168. #endif
  169.    
  170.     cin >> n >> m;
  171.     for (int i = 1; i <= n; ++i) {
  172.         cin >> arr[i];
  173.         nums[arr[i]].em(i);
  174.     }
  175.     for (int i = 0; i <= n; ++i) {
  176.         fenv[i] = nullptr;
  177.     }
  178.     int actInd = 0;
  179.     for (int i = 0; i <= n; ++i) {
  180.         nums[i].em(0);
  181.         nums[i].em(n + 1 + i);
  182.         for (auto it = ++nums[i].rbegin(); it != nums[i].rend(); ++it) {
  183.             int nextValue = *(--it);
  184.             ++it;
  185.             //add(*it, i, nextValue);
  186.             preBuild[actInd++] = tuple<int, int, int>(nextValue, i, *it);
  187.         }
  188.     }
  189.     sort(preBuild, preBuild + actInd);
  190.     for (int i = 0; i < actInd; ++i) {
  191.         int a, b, c;
  192.         tie(a, b, c) = preBuild[i];
  193.         build(c, b, a);
  194.     }
  195.     for (int i = 0; i < m; ++i) {
  196.         char a;
  197.         cin >> a;
  198.         if (a == '?') {
  199.             int l, r;
  200.             cin >> l >> r;
  201.             cout << get(l, r) << "\n";
  202.         }
  203.         else {
  204.             int l, val;
  205.             cin >> l >> val;
  206.             erase(l, *nums[arr[l]].upper_bound(l));
  207.             erase(*(--nums[arr[l]].lower_bound(l)), l);
  208.             add(*(--nums[arr[l]].lower_bound(l)), arr[l], *nums[arr[l]].upper_bound(l));
  209.             nums[arr[l]].erase(l);
  210.             arr[l] = val;
  211.             nums[val].em(l);
  212.             erase(*(--nums[val].lower_bound(l)), *nums[val].upper_bound(l));
  213.             add(*(--nums[val].lower_bound(l)), val, l);
  214.             add(l, val, *nums[val].upper_bound(l));
  215.         }
  216.     }
  217.  
  218.     return 0;
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement