#include <bits/stdc++.h>
using namespace std;
const int maxn = 150010;
inline int read() {
  int x = 0, f = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') f |= ch == '-', ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  return f ? -x : x;
}
int n, q, p, cov[maxn * 4], a[maxn];
struct fuck {
  int x[5], cnt[5];
  fuck() {
    memset(x, 0, sizeof(x));
    memset(cnt, 0, sizeof(cnt));
  }
  void insert(int x_, int cnt_) {
    for (int i = (0); i <= (p - 1); i++)
      if (x_ == x[i]) return void(cnt[i] += cnt_);
    for (int i = (0); i <= (p - 1); i++)
      if (!x[i]) return void((x[i] = x_, cnt[i] = cnt_));
    int mn = 0;
    for (int i = (1); i <= (p - 1); i++)
      if (x[i] && cnt[i] < cnt[mn]) mn = i;
    if (cnt_ < cnt[mn])
      for (int i = (0); i <= (p - 1); i++) cnt[i] -= cnt_;
    else {
      int tmp = cnt[mn];
      x[mn] = x_;
      cnt[mn] = cnt_;
      for (int i = (0); i <= (p - 1); i++) cnt[i] -= tmp;
    }
  }
  fuck operator+(fuck f) const {
    fuck ans = *this;
    for (int i = (0); i <= (p - 1); i++)
      if (f.x[i]) ans.insert(f.x[i], f.cnt[i]);
    return ans;
  }
} seg[maxn * 4];
inline void cover(int o, int l, int r, int v) {
  for (int i = (0); i <= (p - 1); i++) seg[o].x[i] = seg[o].cnt[i] = 0;
  seg[o].x[0] = v;
  seg[o].cnt[0] = r - l + 1;
  cov[o] = v;
}
inline void pushdown(int o, int l, int r) {
  if (cov[o]) {
    int mid = (l + r) >> 1;
    cover(o << 1, l, mid, cov[o]);
    cover(o << 1 | 1, mid + 1, r, cov[o]);
    cov[o] = 0;
  }
}
void build(int o, int l, int r) {
  if (l == r) return void((seg[o].x[0] = a[l], seg[o].cnt[0] = 1));
  int mid = (l + r) >> 1;
  build(o << 1, l, mid);
  build(o << 1 | 1, mid + 1, r);
  seg[o] = seg[o << 1] + seg[o << 1 | 1];
}
void update(int o, int l, int r, int ql, int qr, int v) {
  if (l >= ql && r <= qr) return cover(o, l, r, v);
  pushdown(o, l, r);
  int mid = (l + r) >> 1;
  if (mid >= ql) update(o << 1, l, mid, ql, qr, v);
  if (mid < qr) update(o << 1 | 1, mid + 1, r, ql, qr, v);
  seg[o] = seg[o << 1] + seg[o << 1 | 1];
}
fuck query(int o, int l, int r, int ql, int qr) {
  if (l >= ql && r <= qr) return seg[o];
  pushdown(o, l, r);
  int mid = (l + r) >> 1;
  if (mid < ql) return query(o << 1 | 1, mid + 1, r, ql, qr);
  if (mid >= qr) return query(o << 1, l, mid, ql, qr);
  return query(o << 1, l, mid, ql, qr) + query(o << 1 | 1, mid + 1, r, ql, qr);
}
int main() {
  n = read();
  q = read();
  p = 100 / read();
  for (int i = (1); i <= (n); i++) a[i] = read();
  build(1, 1, n);
  while (q--) {
    int op = read(), x = read(), y = read();
    if (op == 1)
      update(1, 1, n, x, y, read());
    else {
      fuck ans = query(1, 1, n, x, y);
      printf("%d ", p);
      for (int i = (0); i <= (p - 1); i++) printf("%d ", ans.x[i]);
      puts("");
    }
  }
}
