#include <bits/stdc++.h>
using namespace std;
int p1, p;
template <class free>
inline void Min(free&, free);
struct data1 {
  int a[2][10], n;
  inline data1 operator+(const data1& x) const {
    static int b[150050];
    data1 y{};
    for (int i(1); i <= n; ++i) y.a[0][++y.n] = a[0][i], b[a[0][i]] += a[1][i];
    for (int i(1); i <= x.n; ++i) {
      if (!b[x.a[0][i]]) y.a[0][++y.n] = x.a[0][i];
      b[x.a[0][i]] += x.a[1][i];
    }
    for (int i(1); i <= y.n; ++i) y.a[1][i] = b[y.a[0][i]], b[y.a[0][i]] = 0;
    if (y.n < p1) return y;
    for (int i(p1), j, mn; i <= y.n; ++i) {
      for (j = 1, mn = 0x3f3f3f3f; j < p1; ++j) Min(mn, y.a[1][j]);
      Min(mn, y.a[1][i]);
      for (j = 1; j < p1; ++j) y.a[1][j] -= mn;
      if (y.a[1][i] -= mn, !y.a[1][i]) continue;
      for (j = 1; j < p1; ++j)
        if (!y.a[1][j]) {
          y.a[0][j] = y.a[0][i];
          y.a[1][j] = y.a[1][i];
          break;
        }
    }
    if (p == 50) {
      bool pd(false);
      for (int i(1); i < p1; ++i) pd |= y.a[1][i];
      if (!pd)
        for (int i(1); i < p1; ++i) y.a[1][i] = 1;
    }
    return y.n = p1 - 1, y;
  }
  inline void print() {
    printf("%d", min(n, p1 - 1));
    for (int i(1); i <= n && i < p1; ++i) printf(" %d", a[0][i]);
    putchar('\n');
  }
};
struct data {
  int l, r, t;
  data1 d;
} t[150050 << 2];
inline void read(int&), build(int, int, int), change(int, int, int, int),
    update(int, int), spread(int);
inline data1 ask(int, int, int);
int main() {
  int n, m;
  read(n), read(m), read(p);
  p1 = 100 / p + 1, build(1, 1, n);
  for (int i(1), op, l, r, v; i <= m; ++i) {
    read(op), read(l), read(r);
    if (op ^ 2)
      read(v), change(1, l, r, v);
    else
      ask(1, l, r).print();
  }
  return 0;
}
inline data1 ask(int p, int x, int y) {
  if (x <= t[p].l && t[p].r <= y) return t[p].d;
  spread(p);
  data1 ans{};
  int mid(t[p].l + t[p].r >> 1), pl(p << 1), pr(pl | 1);
  if (x <= mid) ans = ans + ask(pl, x, y);
  if (mid < y) ans = ans + ask(pr, x, y);
  return ans;
}
inline void spread(int p) {
  if (t[p].t) update(p << 1, t[p].t), update(p << 1 | 1, t[p].t), t[p].t = 0;
}
inline void update(int p, int v) {
  t[p].d.n = 1, t[p].t = t[p].d.a[0][1] = v;
  t[p].d.a[1][1] = t[p].r - t[p].l + 1;
}
inline void change(int p, int x, int y, int z) {
  if (x <= t[p].l && t[p].r <= y) return update(p, z);
  spread(p);
  int mid(t[p].l + t[p].r >> 1), pl(p << 1), pr(pl | 1);
  if (x <= mid) change(pl, x, y, z);
  if (mid < y) change(pr, x, y, z);
  t[p].d = t[pl].d + t[pr].d;
}
inline void build(int p, int l, int r) {
  if (t[p].l = l, t[p].r = r, l == r)
    return t[p].d.a[1][1] = 1, t[p].d.n = 1, read(t[p].d.a[0][1]);
  int mid(l + r >> 1), pl(p << 1), pr(pl | 1);
  build(pl, l, mid), build(pr, mid + 1, r);
  t[p].d = t[pl].d + t[pr].d;
}
inline void read(int& x) {
  x ^= x;
  register char c;
  while (c = getchar(), c < '0' || c > '9')
    ;
  while (c >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
}
template <class free>
inline void Min(free& x, free y) {
  x = x < y ? x : y;
}
