#include <bits/stdc++.h>
using namespace std;
const int N = 1.5e5 + 5;
int n, m, p, a[N];
template <typename _Tp>
inline void IN(_Tp& x) {
  char ch;
  bool flag = 0;
  x = 0;
  while (ch = getchar(), !isdigit(ch))
    if (ch == '-') flag = 1;
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  if (flag) x = -x;
}
namespace Segment_Tree {
int tag[N << 2], len[N << 2];
vector<pair<int, int>> S[N << 2];
inline bool cmp(pair<int, int> x, pair<int, int> y) {
  return x.second > y.second;
}
inline vector<pair<int, int>> merge(vector<pair<int, int>> x,
                                    vector<pair<int, int>> y) {
  vector<pair<int, int>> tmp = x;
  for (int i = 0; i < (int)y.size(); ++i) {
    bool flag = false;
    for (int j = 0; j < (int)x.size(); ++j)
      if (tmp[j].first == y[i].first) tmp[j].second += y[i].second, flag = true;
    if (!flag) tmp.push_back(y[i]);
  }
  sort(tmp.begin(), tmp.end(), cmp);
  while ((int)tmp.size() >= p) {
    for (int i = 0; i < p; ++i) tmp[i].second -= tmp[tmp.size() - 1].second;
    tmp.pop_back();
  }
  return tmp;
}
void build(int x, int l, int r) {
  len[x] = r - l + 1;
  if (l == r) return S[x].push_back(make_pair(a[l], 1)), void();
  build(((x) << 1), l, ((l + r) >> 1)),
      build(((x) << 1 | 1), ((l + r) >> 1) + 1, r);
  S[x] = merge(S[((x) << 1)], S[((x) << 1 | 1)]);
}
void change(int x, int v) {
  S[x].clear(), tag[x] = v, S[x].push_back((pair<int, int>){v, len[x]});
}
void pushdown(int x) {
  change(((x) << 1), tag[x]), change(((x) << 1 | 1), tag[x]), tag[x] = 0;
}
void update(int x, int l, int r, int L, int R, int v) {
  if (L <= l && r <= R) return change(x, v), void();
  if (tag[x]) pushdown(x);
  if (L <= ((l + r) >> 1)) update(((x) << 1), l, ((l + r) >> 1), L, R, v);
  if (R > ((l + r) >> 1))
    update(((x) << 1 | 1), ((l + r) >> 1) + 1, r, L, R, v);
  S[x] = merge(S[((x) << 1)], S[((x) << 1 | 1)]);
}
vector<pair<int, int>> query(int x, int l, int r, int L, int R) {
  if (L == l && R == r) return S[x];
  if (tag[x]) pushdown(x);
  if (R <= ((l + r) >> 1))
    return query(((x) << 1), l, ((l + r) >> 1), L, R);
  else if (L > ((l + r) >> 1))
    return query(((x) << 1 | 1), ((l + r) >> 1) + 1, r, L, R);
  else
    return merge(
        query(((x) << 1), l, ((l + r) >> 1), L, ((l + r) >> 1)),
        query(((x) << 1 | 1), ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, R));
}
}  // namespace Segment_Tree
using namespace Segment_Tree;
int main() {
  IN(n), IN(m), IN(p), p = 100 / p + 1;
  for (int i = 1; i <= n; ++i) IN(a[i]);
  build(1, 1, n);
  int op, l, r, id;
  vector<pair<int, int>> ans;
  for (int i = 1; i <= m; ++i) {
    IN(op), IN(l), IN(r);
    if (op == 1)
      IN(id), update(1, 1, n, l, r, id);
    else {
      ans = query(1, 1, n, l, r);
      printf("%d ", (int)ans.size());
      for (auto tmp : ans) printf("%d ", tmp.first);
      puts("");
    }
  }
  return 0;
}
