Advertisement
ThegeekKnight16

Seg persistente

Apr 2nd, 2023
1,094
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.20 KB | None | 0 0
  1. /*
  2.     Template de seg persistente
  3.    
  4.     Nesse codigo a seg eh um vetor de marcacao e as queries
  5.     perguntam quantos numeros que estao entre X e Y, inclusive,
  6.     dentro de um intervalo [L, R]
  7.    
  8.     1 <= N, Q <= 1e5
  9.     |X| <= 1e9
  10.     |Y| <= 1e9
  11.     |v[i]| <= 1e9
  12.     1 <= L, R <= N
  13. */
  14. #include <bits/stdc++.h>
  15. using namespace std;
  16. const int border = 1e9 + 10;
  17. vector<int> seg, e, d;
  18.  
  19. int create()
  20. {
  21.     seg.push_back(0);
  22.     e.push_back(0);
  23.     d.push_back(0);
  24.     return seg.size()-1;
  25. }
  26.  
  27. void copy(int pos, int novo)
  28. {
  29.     seg[novo] = seg[pos];
  30.     e[novo] = e[pos];
  31.     d[novo] = d[pos];
  32. }
  33.  
  34. int update(int pos, int ini, int fim, int id, int val)
  35. {
  36.     if (id < ini || id > fim) return pos;
  37.     int novo = create();
  38.     copy(pos, novo);
  39.     if (ini == fim)
  40.     {
  41.         seg[novo] += val;
  42.         return novo;
  43.     }
  44.     int m = (ini + fim) >> 1;
  45.     if (id <= m)
  46.     {
  47.         //Pra n dar erro no c++11
  48.         int aux = update(e[novo], ini, m, id, val);
  49.         e[novo] = aux;
  50.     }
  51.     else
  52.     {
  53.         int aux = update(d[novo], m+1, fim, id, val);
  54.         d[novo] = aux;
  55.     }
  56.     seg[novo] = seg[e[novo]] + seg[d[novo]];
  57.     return novo;
  58. }
  59.  
  60.  
  61. int query(int posL, int posR, int ini, int fim, int p, int q)
  62. {
  63.     if (posL == 0 && posR == 0) return 0;
  64.     if (q < ini || p > fim) return 0;
  65.     if (p <= ini && fim <= q) return (seg[posR] - seg[posL]);
  66.     int m = (ini + fim) >> 1;
  67.     return (query(e[posL], e[posR], ini, m, p, q) + query(d[posL], d[posR], m+1, fim, p, q));
  68. }
  69.  
  70. int main()
  71. {
  72.     ios_base::sync_with_stdio(false);
  73.     cin.tie(NULL);
  74.     //Lendo um vetor de tamanho N
  75.     int N;
  76.     cin >> N;
  77.     vector<int> v(N+1);
  78.     for (int i = 1; i <= N; i++) cin >> v[i];
  79.    
  80.     //Atualiza a seg persistente, a raiz eh o primeiro node de cada
  81.     // "tempo" da seg
  82.     vector<int> raiz(N+1);
  83.     create();
  84.     raiz[0] = create();
  85.    
  86.     for (int i = 1; i <= N; i++)
  87.     {
  88.         raiz[i] = update(raiz[i-1], -border, +border, v[i], +1);
  89.     }
  90.    
  91.     int Q;
  92.     cin >> Q;
  93.     while (Q--)
  94.     {
  95.         int L, R, X, Y;
  96.         cin >> L >> R >> X >> Y;
  97.         cout << query(raiz[L-1], raiz[R], -border, border, X, Y) << '\n';
  98.     }
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement