#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void Read(T &n) {
  char ch;
  bool flag = 0;
  while (!isdigit(ch = getchar()))
    if (ch == '-') flag = 1;
  for (n = ch ^ 48; isdigit(ch = getchar());
       n = (n << 1) + (n << 3) + (ch ^ 48))
    ;
  if (flag) n = -n;
}
enum { MAXN = 150005 };
int n, m, req;
struct node {
  int mx[6], num[6], cnt;
  node() { cnt = 0; }
  inline node operator+(const node &k) {
    node res = k;
    for (register int i = 1; i <= cnt; i++) {
      char has = false;
      for (register int j = 1; j <= res.cnt; j++)
        if (mx[i] == res.mx[j]) {
          res.num[j] += num[i];
          has = true;
          break;
        }
      if (has) continue;
      if (res.cnt < req) {
        res.cnt++;
        res.mx[res.cnt] = mx[i];
        res.num[res.cnt] = num[i];
        continue;
      }
      int mn = 1;
      for (register int j = 1; j <= res.cnt; j++)
        if (res.num[j] < res.num[mn]) mn = j;
      if (num[i] < res.num[mn])
        for (register int j = 1; j <= res.cnt; j++) res.num[j] -= num[i];
      else {
        int tmp = res.num[mn];
        res.mx[mn] = mx[i];
        res.num[mn] = num[i];
        for (register int j = 1; j <= res.cnt; j++) res.num[j] -= tmp;
      }
    }
    return res;
  }
} t[MAXN << 2];
int sz[MAXN << 2], fil[MAXN << 2];
inline int lc(int x) { return x << 1; }
inline int rc(int x) { return x << 1 | 1; }
inline void Fill(int x, int fil) {
  t[x].cnt = 1;
  t[x].mx[1] = fil;
  t[x].num[1] = sz[x];
  ::fil[x] = fil;
}
inline void Push_Down(int x) {
  if (fil[x]) Fill(lc(x), fil[x]), Fill(rc(x), fil[x]), fil[x] = 0;
}
int a[MAXN];
void Build(int x, int head, int tail) {
  sz[x] = tail - head + 1;
  if (head == tail) {
    t[x].cnt = 1;
    t[x].mx[1] = a[head];
    t[x].num[1] = 1;
    return;
  }
  int mid = head + tail >> 1;
  Build(lc(x), head, mid);
  Build(rc(x), mid + 1, tail);
  t[x] = t[lc(x)] + t[rc(x)];
}
void Fill(int x, int head, int tail, int l, int r, int fil) {
  if (l <= head and tail <= r) return Fill(x, fil);
  Push_Down(x);
  int mid = head + tail >> 1;
  if (l <= mid) Fill(lc(x), head, mid, l, r, fil);
  if (mid < r) Fill(rc(x), mid + 1, tail, l, r, fil);
  t[x] = t[lc(x)] + t[rc(x)];
}
node Query(int x, int head, int tail, int l, int r) {
  if (l <= head and tail <= r) return t[x];
  Push_Down(x);
  int mid = head + tail >> 1;
  if (r <= mid) return Query(lc(x), head, mid, l, r);
  if (mid < l) return Query(rc(x), mid + 1, tail, l, r);
  return Query(lc(x), head, mid, l, r) + Query(rc(x), mid + 1, tail, l, r);
}
int main() {
  Read(n);
  Read(m);
  Read(req);
  req = 100 / req;
  for (register int i = 1; i <= n; i++) Read(a[i]);
  Build(1, 1, n);
  while (m--) {
    int opt;
    Read(opt);
    if (opt == 1) {
      int l, r, fil;
      Read(l);
      Read(r);
      Read(fil);
      Fill(1, 1, n, l, r, fil);
    }
    if (opt == 2) {
      int l, r;
      Read(l);
      Read(r);
      node res = Query(1, 1, n, l, r);
      printf("%d ", res.cnt);
      for (register int i = 1; i <= res.cnt; i++) printf("%d ", res.mx[i]);
      puts("");
    }
  }
  return 0;
}
