#include <bits/stdc++.h>
using namespace std;
const int N = 150003;
int n, m, p;
struct Node {
  int num, tag, a[5], b[5];
  inline Node operator=(const Node &o) {
    num = o.num;
    tag = 0;
    memcpy(a, o.a, sizeof a);
    memcpy(b, o.b, sizeof b);
    return *this;
  }
  inline Node operator+(const Node &o) const {
    Node res = o;
    for (register int i = 0; i < num; i++) {
      bool flag = false;
      for (register int j = 0; j < res.num && !flag; j++)
        if (a[i] == res.a[j]) {
          res.b[j] += b[i];
          flag = true;
        }
      if (flag) continue;
      if (res.num < p) {
        res.a[res.num] = a[i];
        res.b[res.num] = b[i];
        ++res.num;
        continue;
      }
      int k = 0;
      for (register int j = 1; j < res.num; j++)
        if (res.b[j] < res.b[k]) k = j;
      if (b[i] < res.b[k])
        for (register int j = 0; j < res.num; j++) res.b[j] -= b[i];
      else {
        int tmp = res.b[k];
        res.a[k] = a[i];
        res.b[k] = b[i];
        for (register int j = 0; j < res.num; j++) res.b[j] -= tmp;
      }
    }
    return res;
  }
} seg[N << 2];
inline void pushup(int x) { seg[x] = seg[x << 1] + seg[x << 1 | 1]; }
inline void pushtag(int x, int len, int val) {
  seg[x].num = 1;
  seg[x].tag = seg[x].a[0] = val;
  seg[x].b[0] = len;
}
inline void pushdown(int x, int len) {
  if (seg[x].tag) {
    pushtag(x << 1, len - (len >> 1), seg[x].tag);
    pushtag(x << 1 | 1, len >> 1, seg[x].tag);
    seg[x].tag = 0;
  }
}
inline void build(int x, int L, int R) {
  if (L == R) {
    scanf("%d", &seg[x].a[0]);
    seg[x].b[0] = seg[x].num = 1;
    return;
  }
  int mid = L + R >> 1;
  build(x << 1, L, mid);
  build(x << 1 | 1, mid + 1, R);
  pushup(x);
}
inline void modify(int x, int L, int R, int l, int r, int val) {
  if (l <= L && R <= r) {
    pushtag(x, R - L + 1, val);
    return;
  }
  int mid = L + R >> 1;
  pushdown(x, R - L + 1);
  if (l <= mid) modify(x << 1, L, mid, l, r, val);
  if (mid < r) modify(x << 1 | 1, mid + 1, R, l, r, val);
  pushup(x);
}
inline Node query(int x, int L, int R, int l, int r) {
  if (l <= L && R <= r) return seg[x];
  int mid = L + R >> 1;
  pushdown(x, R - L + 1);
  if (r <= mid)
    return query(x << 1, L, mid, l, r);
  else if (mid < l)
    return query(x << 1 | 1, mid + 1, R, l, r);
  else
    return query(x << 1, L, mid, l, r) + query(x << 1 | 1, mid + 1, R, l, r);
}
int main() {
  scanf("%d%d%d", &n, &m, &p);
  p = 100 / p;
  build(1, 1, n);
  while (m--) {
    int opt, l, r, val;
    scanf("%d%d%d", &opt, &l, &r);
    if (opt == 1) {
      scanf("%d", &val);
      modify(1, 1, n, l, r, val);
    } else {
      Node now = query(1, 1, n, l, r);
      printf("%d", now.num);
      for (register int i = 0; i < now.num; i++) printf(" %d", now.a[i]);
      putchar('\n');
    }
  }
}
