GastonFontenla

Salary CSES con segment tree

Jun 27th, 2019
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.60 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int ST_SIZE = 2097152;
  6. int st[ST_SIZE];
  7. int leftmost[ST_SIZE];
  8. int rightmost[ST_SIZE];
  9. int p[200000];
  10. char t[200000];
  11. int a[200000];
  12. int b[200000];
  13. int dif[600000];
  14. int n, q, n2;
  15. int tam;
  16.  
  17. void preprocesamiento()
  18. {
  19.     int tamDif = 0;
  20.     unordered_map <int, int> mapa;
  21.     scanf("%d %d", &n, &q);
  22.  
  23.     for(int i=0; i<n; i++)
  24.     {
  25.         scanf("%d", &p[i]);
  26.         dif[tamDif++] = p[i];
  27.     }
  28.  
  29.     for(int i=0; i<q; i++)
  30.     {
  31.         scanf(" %c %d %d", &t[i], &a[i], &b[i]);
  32.         if(t[i] == '?')
  33.             dif[tamDif++] = a[i];
  34.         dif[tamDif++] = b[i];
  35.     }
  36.  
  37.     sort(dif, dif+tamDif);
  38.     int valor = 2;
  39.     mapa[dif[0]] = 1;
  40.     for(int i=1; i<tamDif; i++)
  41.     {
  42.         valor += dif[i] != dif[i-1];
  43.         mapa[dif[i]] = valor;
  44.     }
  45.  
  46.     for(int i=0; i<n; i++)
  47.         p[i] = mapa[p[i]];
  48.  
  49.     for(int i=0; i<q; i++)
  50.     {
  51.         if(t[i] == '?')
  52.             a[i] = mapa[a[i]];
  53.         b[i] = mapa[b[i]];
  54.     }
  55.     tam = mapa.size();
  56. }
  57.  
  58. int sigPot2(int val)
  59. {
  60.     int pot = 1;
  61.     while(pot < val)
  62.         pot *= 2;
  63.     return pot;
  64. }
  65.  
  66. int valUpdate;
  67. int pos;
  68. int update(int nodo)
  69. {
  70.     if(nodo == pos && nodo >= n2)
  71.     {
  72.         st[nodo] += valUpdate; ///sumar o restar
  73.         return st[nodo];
  74.     }
  75.  
  76.     if(leftmost[nodo] <= pos && pos <= rightmost[nodo])
  77.     {
  78.         st[nodo] = update(nodo<<1) + update((nodo<<1)|1);
  79.     }
  80.  
  81.     return st[nodo];
  82. }
  83.  
  84. int l, r;
  85. int query(int nodo)
  86. {
  87.     ///Si el rango está completamente contenido
  88.     if(l <= leftmost[nodo] && rightmost[nodo] <= r)
  89.         return st[nodo];
  90.  
  91.     ///Si no se superponen
  92.     if(rightmost[nodo] < l || leftmost[nodo] > r)
  93.         return 0;
  94.  
  95.     return query(nodo<<1)+query((nodo<<1)|1);
  96. }
  97.  
  98. int main()
  99. {
  100.     preprocesamiento();
  101.  
  102.     n2 = sigPot2(tam);
  103.  
  104.     for(int i=n2; i<n2*2; i++)
  105.         leftmost[i] = rightmost[i] = i;
  106.  
  107.     for(int i=n2-1; i>=1; i--)
  108.     {
  109.         leftmost[i] = leftmost[i<<1];
  110.         rightmost[i] = rightmost[(i<<1)|1];
  111.     }
  112.  
  113.     for(int i=0; i<n; i++)
  114.     {
  115.         valUpdate = 1;
  116.         pos = n2+p[i]-1;
  117.         update(1);
  118.     }
  119.  
  120.     for(int i=0; i<q; i++)
  121.     {
  122.         if(t[i] == '!')
  123.         {
  124.             valUpdate = -1;
  125.             pos = n2+p[a[i]-1]-1;
  126.             update(1);
  127.  
  128.             p[a[i]-1] = b[i];
  129.  
  130.             valUpdate = 1;
  131.             pos = n2+p[a[i]-1]-1;
  132.             update(1);
  133.         }
  134.         else
  135.         {
  136.             l = n2+a[i]-1;
  137.             r = n2+b[i]-1;
  138.             printf("%d\n", query(1));
  139.         }
  140.     }
  141.  
  142.     return 0;
  143. }
Advertisement
Add Comment
Please, Sign In to add comment