Advertisement
DuongNhi99

ORDERSET (Segment Tree)

Mar 10th, 2022
614
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.77 KB | None | 0 0
  1. /*
  2. Khởi tạo toàn bộ cây có giá trị bằng 0.
  3. Tại mỗi lá, nếu lá đó trong S có giá trị bằng thứ tự của lá đó, ta sẽ cập nhập lá đó bằng 1, và cập nhật lại toàn bộ cây.
  4. */
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7.  
  8. const int N = 200001;
  9. int n, x;
  10. char s[N];
  11. int a[N], b[N], pos[N], c[N];
  12. int st[N * 5];
  13.  
  14. void build(int id, int l, int r)
  15. {
  16.     if (l == r) {
  17.         pos[l] = id;
  18.         st[id] = 0;
  19.         return;
  20.     }
  21.    
  22.     int mid = (l+r) / 2;
  23.     build(id * 2, l, mid);
  24.     build(id * 2 + 1, mid + 1, r);
  25.    
  26.     st[id] = st[id*2] + st[id*2+1];
  27.     st[id] = 0;
  28. }
  29.  
  30. int get(int id, int l, int r, int u, int v)
  31. {
  32.     if (v < l || u > r)
  33.         return 0;
  34.     if (u <= l && r <= v)
  35.         return st[id];
  36.        
  37.     int mid = (l+r) / 2;
  38.     int t1 = get(id*2, l, mid, u, v);
  39.     int t2 = get(id*2+1, mid + 1, r, u, v);
  40.    
  41.     return t1 + t2;
  42. }
  43.  
  44. void tinh() {
  45.     for (int i = 1; i <= n; i++)
  46.     {
  47.         //Khi nhập vào lệnh INSERT(S,x)
  48.         if (s[i] == 'I') {
  49.             int id = pos[b[i]];
  50.             st[id] = 1;
  51.            
  52.             while (id/2 > 0) {
  53.                 id = id / 2;
  54.                 st[id] = st[2*id] + st[2*id+1];
  55.             }
  56.         }else
  57.        
  58.         //Khi nhập vào lệnh DELETE(S,x)
  59.         if (s[i] == 'D') {
  60.             int id = pos[b[i]];
  61.             st[id] = 0;
  62.            
  63.             while (id/2 > 0) {
  64.                 id = id / 2;
  65.                 st[id] = st[2*id] + st[2*id+1];
  66.             }
  67.         } else
  68.        
  69.         //Khi nhập vào lệnh K-TH(S), cần phải trả về số bé thứ k, ta sử dụng chặt nhị phân để tìm
  70.         if (s[i] == 'K') {
  71.             if (a[i] > get(1, 1, n, 1, n)) {
  72.                 cout << "invalid" << '\n';
  73.                 continue;
  74.             }
  75.            
  76.             int lo = 0, hi = n;  
  77.             while (hi - lo > 1) {
  78.                 int mid = (lo+hi) / 2;
  79.                 if (a[i] <= get(1, 1, n, 1, mid))
  80.                     hi = mid;
  81.                 else lo = mid;
  82.             }
  83.            
  84.             cout << c[hi] << '\n';
  85.         } else
  86.        
  87.         //Khi nhập vào lệnh COUNT(S,x) – đếm số lượng số thuộc S bé hơn x, ta tính tổng tất cả các lá từ 1 tới x-1
  88.         cout << get(1, 1, n, 1, b[i]-1) << '\n';
  89.     }
  90.    
  91. }
  92.  
  93. int main()
  94. {
  95.     cin >> n;
  96.     for (int i = 1; i <= n; i++) {
  97.         cin >> s[i] >> a[i];
  98.         c[i] = a[i];
  99.     }
  100.    
  101.     sort(c + 1, c + n + 1);
  102.    
  103.     for (int i = 1; i <= n; i++)
  104.         b[i] = lower_bound(c+1, c+n+1, a[i]) - c;
  105.    
  106.     build(1, 1, n);
  107.    
  108.     tinh();
  109.    
  110.     return 0;
  111.    
  112. }
  113.  
  114.  
  115.  
  116. /*
  117. Bạn cần quản lý một tập hợp động các số, hỗ trợ hai thao tác cơ bản:
  118. INSERT(S,x): nếu x không thuộc S, thêm x vào S
  119. DELETE(S,x): nếu x thuộc S, xóa x khỏi S
  120.  
  121. Hai loại truy vấn:
  122. K-TH(S) : trả về số bé thứ k của S
  123. COUNT(S,x): đếm số lượng số thuộc S bé hơn x
  124.  
  125. Với mỗi truy vấn, in ra kết quả tương ứng trên một dòng. Với truy vấn K-TH, nếu k lớn hơn số phần tử của S, in ra ‘invalid’.
  126.  
  127. 8
  128. I -1
  129. I -1
  130. I 2
  131. C 0
  132. K 2
  133. D -1
  134. K 1
  135. K 2
  136.  
  137. Kết quả
  138. 1
  139. 2
  140. 2
  141. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement