#include <bits/stdc++.h>
using namespace std;
const int maxn = 1.5e5 + 70;
const int INF = 2.1e9;
const int MOD = 1e9 + 7;
int n, m, p, L;
int a[maxn], setv[4 * maxn];
vector<pair<int, int> > V[4 * maxn];
void merge(vector<pair<int, int> >& V, vector<pair<int, int> >& V1,
           vector<pair<int, int> >& V2) {
  V = V1;
  for (int i = 0; i < V2.size(); i++) {
    bool flag = 0;
    for (int j = 0; j < V.size(); j++) {
      if (V2[i].second == V[j].second) {
        V[j].first += V2[i].first;
        flag = 1;
        break;
      }
    }
    if (!flag) V.push_back(V2[i]);
  }
  sort(V.begin(), V.end());
  reverse(V.begin(), V.end());
  while (V.size() > L) {
    for (int i = 0; i < (int)V.size() - 1; i++) V[i].first -= V.back().first;
    V.pop_back();
  }
}
void maintain(int o, int L, int R) {
  if (L == R) {
    V[o].clear();
    V[o].push_back(make_pair(1, setv[o]));
  } else {
    if (setv[o] != -1) {
      V[o].clear();
      V[o].push_back(make_pair(R - L + 1, setv[o]));
    } else {
      int lc = o * 2, rc = o * 2 + 1;
      merge(V[o], V[lc], V[rc]);
    }
  }
}
void build(int o, int L, int R) {
  if (L == R) {
    setv[o] = a[L];
  } else {
    setv[o] = -1;
    int lc = o * 2, rc = o * 2 + 1;
    int M = L + (R - L) / 2;
    build(lc, L, M);
    build(rc, M + 1, R);
  }
  maintain(o, L, R);
}
void pushdown(int o) {
  if (setv[o] != -1) {
    int lc = o * 2, rc = o * 2 + 1;
    setv[lc] = setv[rc] = setv[o];
    setv[o] = -1;
  }
}
int ql, qr, val;
void update(int o, int L, int R) {
  if (ql <= L && qr >= R) {
    setv[o] = val;
  } else {
    pushdown(o);
    int lc = o * 2, rc = o * 2 + 1;
    int M = L + (R - L) / 2;
    if (ql <= M)
      update(lc, L, M);
    else
      maintain(lc, L, M);
    if (qr >= M + 1)
      update(rc, M + 1, R);
    else
      maintain(rc, M + 1, R);
  }
  maintain(o, L, R);
}
vector<pair<int, int> > ans;
void query(int o, int L, int R) {
  if (setv[o] != -1) {
    vector<pair<int, int> > tmp;
    tmp.push_back(make_pair(min(qr, R) - max(ql, L) + 1, setv[o]));
    merge(ans, ans, tmp);
  } else {
    if (ql <= L && qr >= R) {
      merge(ans, ans, V[o]);
    } else {
      int lc = o * 2, rc = o * 2 + 1;
      int M = L + (R - L) / 2;
      if (ql <= M) query(lc, L, M);
      if (qr >= M + 1) query(rc, M + 1, R);
    }
  }
}
int main() {
  while (cin >> n >> m >> p) {
    L = 100 / p;
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(1, 1, n);
    while (m--) {
      int op;
      scanf("%d", &op);
      if (op == 1) {
        scanf("%d%d%d", &ql, &qr, &val);
        update(1, 1, n);
      } else {
        scanf("%d%d", &ql, &qr);
        ans.clear();
        query(1, 1, n);
        printf("%d", (int)ans.size());
        for (int i = 0; i < ans.size(); i++) printf(" %d", ans[i].second);
        printf("\n");
      }
    }
  }
  return 0;
}
