#include <bits/stdc++.h>
using namespace std;
inline int Rd() {
  int s = 0;
  char fl = 0, c = getchar();
  while (c < '0' || c > '9') fl |= (c == '-'), c = getchar();
  while (c >= '0' && c <= '9')
    s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
  return fl ? -s : s;
}
const int N = 1.5e5 + 5;
struct node {
  int val, num;
  inline node(int _val, int _num) { val = _val, num = _num; }
  inline char operator<(const node &u) const { return num > u.num; }
};
int n, m, p, a[N], tag[N << 2], len[N << 2];
vector<node> t[N << 2];
inline vector<node> operator+(const vector<node> &x, const vector<node> &y) {
  vector<node> res = x;
  for (int i = 0; i < y.size(); ++i) {
    char fl = 0;
    for (int j = 0; j < res.size(); ++j)
      if (res[j].val == y[i].val) {
        res[j].num += y[i].num, fl = 1;
        break;
      }
    if (!fl) res.push_back(y[i]);
  }
  sort(res.begin(), res.end());
  while (res.size() > p) {
    for (int i = 0; i < res.size(); ++i) res[i].num -= (--res.end())->num;
    res.pop_back();
  }
  return res;
}
void Build(int x, int l, int r) {
  len[x] = r - l + 1;
  if (l == r) return t[x].push_back(node(a[l], 1)), void();
  int mid = l + r >> 1;
  Build(x << 1, l, mid), Build(x << 1 | 1, mid + 1, r),
      t[x] = t[x << 1] + t[x << 1 | 1];
}
inline void Update(int x, int v) {
  tag[x] = v, t[x].clear(), t[x].push_back(node(v, len[x]));
}
inline void Pushdown(int x) {
  if (tag[x]) Update(x << 1, tag[x]), Update(x << 1 | 1, tag[x]), tag[x] = 0;
}
void Insert(int x, int l, int r, int ql, int qr, int v) {
  if (ql <= l && r <= qr) return Update(x, v);
  Pushdown(x);
  int mid = l + r >> 1;
  if (ql <= mid) Insert(x << 1, l, mid, ql, qr, v);
  if (qr > mid) Insert(x << 1 | 1, mid + 1, r, ql, qr, v);
  t[x] = t[x << 1] + t[x << 1 | 1];
}
vector<node> Query(int x, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr) return t[x];
  Pushdown(x);
  int mid = l + r >> 1;
  if (qr <= mid) return Query(x << 1, l, mid, ql, qr);
  if (ql > mid) return Query(x << 1 | 1, mid + 1, r, ql, qr);
  return Query(x << 1, l, mid, ql, qr) + Query(x << 1 | 1, mid + 1, r, ql, qr);
}
int main() {
  n = Rd(), m = Rd(), p = 100 / Rd();
  for (int i = 1; i <= n; ++i) a[i] = Rd();
  Build(1, 1, n);
  while (m--) {
    int op = Rd(), l = Rd(), r = Rd();
    if (op == 1)
      Insert(1, 1, n, l, r, Rd());
    else {
      vector<node> tmp = Query(1, 1, n, l, r);
      printf("%d ", tmp.size());
      for (int i = 0; i < tmp.size(); ++i) printf("%d ", tmp[i]);
      puts("");
    }
  }
  return 0;
}
