#include <bits/stdc++.h>
using namespace std;
inline int gi() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + ch - 48;
    ch = getchar();
  }
  return x * f;
}
template <typename T>
inline void Max(T &a, T b) {
  if (a < b) a = b;
}
template <typename T>
inline void Min(T &a, T b) {
  if (a > b) a = b;
}
const int N = 5e4 + 7;
int n, m, q, edc, tim, ndc;
int head[N], a[N], fa[N], top[N], in[N], dep[N], zson[N], son[N];
int rt[N];
long long c[N], C;
struct edge {
  int lst, to;
  edge() {}
  edge(int lst, int to) : lst(lst), to(to) {}
} e[N << 1];
void Add(int a, int b) {
  e[++edc] = edge(head[a], b), head[a] = edc;
  e[++edc] = edge(head[b], a), head[b] = edc;
}
void dfs1(int u) {
  son[u] = 1;
  for (int i = head[u], v = e[i].to; i; i = e[i].lst, v = e[i].to)
    if (v ^ fa[u]) {
      dep[v] = dep[u] + 1;
      dfs1(v);
      son[u] += son[v];
      if (son[v] > son[zson[u]]) zson[u] = v;
    }
}
void dfs2(int u, int from) {
  in[u] = ++tim, top[u] = from;
  if (zson[u]) dfs2(zson[u], from);
  for (int i = head[u], v = e[i].to; i; i = e[i].lst, v = e[i].to)
    if (v ^ fa[u] && v ^ zson[u]) dfs2(v, v);
}
struct data {
  long long s1, s2;
  data() { s1 = s2 = 0; }
  data(long long s1, long long s2) : s1(s1), s2(s2) {}
  data operator+(const data &rhs) const {
    return data(s1 + rhs.s1, s2 + rhs.s2);
  }
};
data pls(data t, long long len, long long v) {
  data res;
  res.s2 = t.s2 + 2 * v * t.s1 + len * v * v;
  res.s1 = t.s1 + v * len;
  return res;
}
struct node {
  int l, r;
  long long adv;
  data v;
} t[N * 100];
void pushup(int l, int r, int o) {
  data L, R;
  int mid = l + r >> 1;
  if (t[o].l) L = t[t[o].l].v;
  L = pls(L, mid - l + 1, t[o].adv);
  if (t[o].r) R = t[t[o].r].v;
  R = pls(R, r - mid, t[o].adv);
  t[o].v = L + R;
}
void modify(int L, int R, int l, int r, int &o, long long v) {
  if (!o) o = ++ndc;
  if (L <= l && r <= R) {
    t[o].adv += v;
    t[o].v = pls(t[o].v, r - l + 1, v);
    return;
  }
  int mid = l + r >> 1;
  if (L <= mid) modify(L, R, l, mid, t[o].l, v);
  if (R > mid) modify(L, R, mid + 1, r, t[o].r, v);
  pushup(l, r, o);
}
void upd(int u, int R, int v) {
  for (; u; u = fa[top[u]]) {
    modify(in[top[u]], in[u], 1, n, rt[R], v);
  }
}
int main() {
  n = gi(), m = gi(), q = gi(), C = gi();
  for (int i = 1; i <= n; ++i) a[i] = gi();
  for (int i = 2; i <= n; ++i) {
    fa[i] = gi();
    Add(fa[i], i);
  }
  for (int i = 1; i <= m; ++i) c[i] = gi();
  dep[1] = 1, dfs1(1), dfs2(1, 1);
  for (int i = 1; i <= n; ++i) {
    upd(i, a[i], 1);
  }
  while (q--) {
    int opt = gi();
    if (opt == 1) {
      int x = gi(), w = gi();
      upd(x, a[x], -1);
      upd(x, a[x] = w, 1);
    } else {
      int k = gi();
      printf("%.10lf\n", 1.0 * c[k] / n * c[k] * t[rt[k]].v.s2 + C * C -
                             2.0 * c[k] / n * C * t[rt[k]].v.s1);
    }
  }
  return 0;
}
