#include <bits/stdc++.h>   #pragma GCC optimize( O3 )   #pragma GCC target( sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx )   using namespace std;   using ll = int64_t;   const size_t kBuben = 10;   const int kNone = -1;   struct Pair {     int value, count;   };   struct ByValue {     inline bool operator()(const Pair& a, const Pair& b) const {       return a.value < b.value;     }   };   struct ByCount {     inline bool operator()(const Pair& a, const Pair& b) const {       if (a.count != b.count) return a.count > b.count;       return a.value < b.value;     }   };   struct Segment {     Segment* l;     Segment* r;     array<Pair, kBuben> top;     int len, middle, value_to_push;     Segment(int length) {       l = r = nullptr;       len = length;       clear();     }     inline void clear() {       value_to_push = kNone;       top.fill(Pair{kNone, 0});     }     inline void assign(int value) {       clear();       top[0] = Pair{value, len};       value_to_push = value;     }     inline void rebuild(const Segment& a, const Segment& b) {       array<Pair, 2 * kBuben> result;       array<Pair, kBuben> add;       size_t add_count = 0;       result.fill(Pair{kNone, 0});       add.fill(Pair{kNone, 0});       copy(a.top.begin(), a.top.end(), result.begin());       sort(result.begin(), result.end(), ByValue());       for (const auto& segment : b.top) {         auto it = lower_bound(result.begin(), result.end(), segment, ByValue());         if (it == result.end() || it->value != segment.value) {           add[add_count++] = segment;         } else {           it->count += segment.count;         }       }       copy(add.begin(), add.begin() + add_count, result.begin());       sort(result.begin(), result.end(), ByCount());       copy(result.begin(), result.begin() + kBuben, top.begin());     }   };   Segment* root;   inline bool push(Segment* current) {     if (current->value_to_push != kNone) {       current->l->assign(current->value_to_push);       current->r->assign(current->value_to_push);       current->value_to_push = kNone;       return true;     } else {       return false;     }   }   inline int get_rand(int l, int r) { return l + (rand() % (r - l + 1)); }   Segment* build(int l, int r, const vector<int>& values) {     Segment* current = new Segment(r - l + 1);     if (l == r) {       current->assign(values[l]);     } else {       int m = (l + r) / 2;       current->middle = m;       current->l = build(l, m, values);       current->r = build(m + 1, r, values);       current->rebuild(*current->l, *current->r);     }     return current;   }   void assign(Segment* current, int l, int r, int tl, int tr, int value) {     if (l == tl && r == tr) {       current->assign(value);     } else {       push(current);       int m = current->middle;       if (tl <= m) assign(current->l, l, m, tl, min(m, tr), value);       if (tr > m) assign(current->r, m + 1, r, max(m + 1, tl), tr, value);       current->rebuild(*current->l, *current->r);     }   }   bool get(Segment* current, int l, int r, int tl, int tr, vector<Pair>& bests) {     if (l == tl && r == tr) {       for (const auto& p : current->top) {         bests.push_back(p);       }       return false;     } else {       bool pushed = push(current);       int m = current->middle;       if (tl <= m) pushed |= get(current->l, l, m, tl, min(m, tr), bests);       if (tr > m) pushed |= get(current->r, m + 1, r, max(m + 1, tl), tr, bests);       if (pushed) current->rebuild(*current->l, *current->r);       return pushed;     }   }   int main() {     srand(1224);     ios_base::sync_with_stdio(false);     cin.tie(nullptr);     int n, m, P;     cin >> n >> m >> P;     int k = 100 / P;     vector<int> values(n);     for (int i = 0; i < n; i++) {       cin >> values[i];     }     root = build(0, n - 1, values);     vector<Pair> bests;     vector<Pair> result;     for (int i = 0; i < m; i++) {       int type, l, r, id;       cin >> type >> l >> r;       --l, --r;       if (type == 1) {         cin >> id;         assign(root, 0, n - 1, l, r, id);       } else {         bests.clear();         get(root, 0, n - 1, l, r, bests);         sort(bests.begin(), bests.end(), ByValue());         result.clear();         int i = 0;         while (i < bests.size()) {           int j = i, cnt = 0;           while (j < bests.size() && bests[i].value == bests[j].value) {             cnt += bests[j].count;             ++j;           }           result.push_back(Pair{bests[i].value, cnt});           i = j;         }         sort(result.begin(), result.end(), ByCount());         result.resize(k);         cout << k;         for (const auto& x : result) {           cout <<     << x.value;         }         cout <<   n ;       }     }     return 0;   }