#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmax(T& x, T y) {
  return x < y ? x = y, 1 : 0;
}
template <class T>
bool ckmin(T& x, T y) {
  return x > y ? x = y, 1 : 0;
}
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = 0;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return f ? x : -x;
}
const int N = 150005;
const int T = N << 2;
int n, m, p, a[N], lim;
int tag[T];
struct node {
  int a[5], c[5], num;
  node() {
    num = 0;
    memset(a, 0, sizeof(a));
    memset(c, 0, sizeof(c));
  }
} val[T];
node merge(node a, node b) {
  node res = a;
  for (int i = 0; i < b.num; ++i) {
    bool flg = 0;
    for (int j = 0; j < res.num; ++j)
      if (res.a[j] == b.a[i]) {
        res.c[j] += b.c[i];
        flg = 1;
        break;
      }
    if (flg) continue;
    if (res.num < lim) {
      res.a[res.num] = b.a[i], res.c[res.num] = b.c[i], ++res.num;
      continue;
    }
    int mi = 1919810, id = 0, d = b.c[i];
    for (int j = 0; j < lim; ++j)
      if (ckmin(mi, res.c[j])) id = j;
    if (mi < b.c[i]) d = res.c[id], res.a[id] = b.a[i], res.c[id] = b.c[i];
    for (int j = 0; j < lim; ++j) res.c[j] -= d;
  }
  return res;
}
inline void pushup(int p) { val[p] = merge(val[(p << 1)], val[(p << 1 | 1)]); }
void build(int l, int r, int p) {
  if (l == r) {
    val[p].num = 1, val[p].a[0] = a[l], val[p].c[0] = 1;
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, (p << 1)), build(mid + 1, r, (p << 1 | 1));
  val[p] = merge(val[(p << 1)], val[(p << 1 | 1)]);
}
inline void pushdown(int p, int l, int r) {
  if (tag[p]) {
    int mid = (l + r) >> 1;
    val[(p << 1)].num = 1, val[(p << 1)].a[0] = tag[p],
              val[(p << 1)].c[0] = mid - l + 1;
    val[(p << 1 | 1)].num = 1, val[(p << 1 | 1)].a[0] = tag[p],
                  val[(p << 1 | 1)].c[0] = r - mid;
    tag[(p << 1)] = tag[p], tag[(p << 1 | 1)] = tag[p], tag[p] = 0;
  }
}
inline void update(int ql, int qr, int d, int l, int r, int p) {
  if (ql <= l && r <= qr) {
    tag[p] = d;
    val[p].num = 1, val[p].a[0] = d, val[p].c[0] = r - l + 1;
    return;
  }
  pushdown(p, l, r);
  int mid = (l + r) >> 1;
  if (ql <= mid) update(ql, qr, d, l, mid, (p << 1));
  if (mid < qr) update(ql, qr, d, mid + 1, r, (p << 1 | 1));
  pushup(p);
}
inline node query(int ql, int qr, int l, int r, int p) {
  if (ql <= l && r <= qr) return val[p];
  pushdown(p, l, r);
  int mid = (l + r) >> 1;
  node res;
  if (ql <= mid) res = merge(res, query(ql, qr, l, mid, (p << 1)));
  if (mid < qr) res = merge(res, query(ql, qr, mid + 1, r, (p << 1 | 1)));
  return res;
}
signed main() {
  n = read(), m = read(), p = read(), lim = 100 / p;
  for (int i = 1, iend = n; i <= iend; ++i) a[i] = read();
  build(1, n, 1);
  while (m--) {
    int op = read(), l = read(), r = read();
    if (op == 1) {
      int x = read();
      update(l, r, x, 1, n, 1);
    } else {
      node res = query(l, r, 1, n, 1);
      printf("%d ", res.num);
      for (int i = 0; i < res.num; ++i) printf("%d ", res.a[i]);
      puts("");
    }
  }
  return 0;
}
