Advertisement
kdzhr

Simple String Queries

Apr 9th, 2020
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.78 KB | None | 0 0
  1. // WA&TLE https://atcoder.jp/contests/abc157/tasks/abc157_e
  2.  
  3. #include <vector>
  4. #include <set>
  5. #include <iostream>
  6.  
  7. struct segment_tree {
  8.     void build(std::string const &a) {
  9.         t.resize(4 * a.size());
  10.         build(0, 0, a.size(), a);
  11.     }
  12.  
  13.     void update(size_t pos, char new_value) {
  14.         update(0, 0, t.size() / 4, pos, new_value);
  15.     }
  16.  
  17.     int32_t get(size_t l, size_t r) {
  18.         return get(0, 0, t.size() / 4, l, r + 1).size();
  19.     }
  20.  
  21. private:
  22.     std::vector<std::set<char>> t;
  23.     void build(size_t v, size_t l, size_t r, std::string const &a) {
  24.         if (l + 1 == r) {
  25.             std::set<char> m;
  26.             m.insert(a[l]);
  27.             t[v] = m;
  28.         } else {
  29.             size_t mid = (l + r) / 2;
  30.             build(2 * v + 1, l, mid, a);
  31.             build(2 * v + 2, mid, r, a);
  32.             for (auto elem : t[2 * v + 1]) {
  33.                 t[v].insert(elem);
  34.             }
  35.             for (auto elem : t[2 * v + 2]) {
  36.                 t[v].insert(elem);
  37.             }
  38.         }
  39.     }
  40.  
  41.     void update(size_t v, size_t l, size_t r, size_t pos, char new_value) {
  42.         if (l + 1 == r) {
  43.             std::set<char> m;
  44.             m.insert(new_value);
  45.             t[v] = m;
  46.         } else {
  47.             size_t mid = (l + r) / 2;
  48.             if (pos < mid) {
  49.                 update(2 * v + 1, l, mid, pos, new_value);
  50.             } else {
  51.                 update(2 * v + 2, mid, r, pos, new_value);
  52.             }
  53.             for (auto elem : t[2 * v + 1]) {
  54.                 t[v].insert(elem);
  55.             }
  56.             for (auto elem : t[2 * v + 2]) {
  57.                 t[v].insert(elem);
  58.             }
  59.         }
  60.     }
  61.  
  62.     std::set<char> get(size_t v, size_t l, size_t r, size_t req_l, size_t req_r) {
  63.         if (req_l >= req_r) {
  64.             return std::set<char> ();
  65.         } else if (l == req_l && r == req_r) {
  66.             return t[v];
  67.         } else {
  68.             size_t mid = (l + r) / 2;
  69.             std::set<char> cur = get(2 * v + 1, l, mid, req_l, std::min(mid, req_r));
  70.             for (auto elem : get(2 * v + 2, mid, r, std::max(mid, req_l), req_r)) {
  71.                 cur.insert(elem);
  72.             }
  73.             return cur;
  74.         }
  75.     }
  76. };
  77.  
  78. int main() {
  79.     std::ios_base::sync_with_stdio(false);
  80.     segment_tree chr;
  81.     size_t n;
  82.     std::string a;
  83.     std::cin >> n >> a;
  84.     chr.build(a);
  85.     size_t k;
  86.     std::cin >> k;
  87.     while (k-- > 0) {
  88.         size_t type;
  89.         std::cin >> type;
  90.         if (type == 1) {
  91.             size_t pos;
  92.             char ch;
  93.             std::cin >> pos >> ch;
  94.             chr.update(pos - 1, ch);
  95.         } else {
  96.             size_t l, r;
  97.             std::cin >> l >> r;
  98.             std::cout << chr.get(l - 1, r - 1) << '\n';
  99.         }
  100.     }
  101.  
  102.     return 0;
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement