#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
int n, m, q, cost;
int a[N], b[N], c[N], cPar[N], h[N], sz[N];
long long sumDist[N], sumCount[N], sumHeight[N];
bool dead[N];
vector<int> adj[N];
map<int, long long> sum[N], cnt[N], height[N], sumPar[N];
int OneCentroid(int root) {
  function<void(int, int)> get_sz = [&](int u, int p) {
    sz[u] = 1;
    for (int v : adj[u])
      if (v != p && !dead[v]) {
        get_sz(v, u);
        sz[u] += sz[v];
      }
  };
  get_sz(root, -1);
  int all_size = sz[root];
  function<int(int, int)> dfs = [&](int u, int p) {
    for (int v : adj[u])
      if (v != p && !dead[v]) {
        if (sz[v] > all_size / 2) return dfs(v, u);
      }
    return u;
  };
  return dfs(root, -1);
}
void DFS(int u, int par = -1) {
  for (int v : adj[u])
    if (v != par) {
      h[v] = h[u] + 1;
      DFS(v, u);
    }
}
void Centroid() {
  function<void(int, int)> rec = [&](int start, int pCentroid) {
    int c = OneCentroid(start);
    cPar[c] = pCentroid;
    dead[c] = true;
    for (int u : adj[c])
      if (!dead[u]) rec(u, c);
    height[c][c] = 0;
    function<void(int, int)> add_cnt = [&](int u, int p) {
      for (int v : adj[u])
        if (v != p && !dead[v]) {
          height[c][v] = height[c][u] + 1;
          add_cnt(v, u);
        }
    };
    add_cnt(c, -1);
    dead[c] = false;
  };
  rec(1, -1);
}
void ChangeAns(int u, int d) {
  int col = a[u], c = u;
  sumDist[col] += d * sum[c][col];
  int nc = c;
  c = cPar[c];
  sumHeight[col] += d * h[u];
  sumCount[col] += d;
  while (c != -1) {
    long long totDist = height[c][u] * (cnt[c][col] - cnt[nc][col]) +
                        (sum[c][col] - sumPar[nc][col]);
    sumDist[col] += d * totDist;
    nc = c;
    c = cPar[c];
  }
}
void ChangeTree(int u, int d) {
  int col = a[u];
  int c = u;
  while (c != -1) {
    cnt[c][col] += d;
    sum[c][col] += d * height[c][u];
    if (cPar[c] != -1) sumPar[c][col] += d * height[cPar[c]][u];
    c = cPar[c];
  }
}
void Update(int u, int col) {
  ChangeAns(u, -1);
  ChangeTree(u, -1);
  a[u] = col;
  ChangeTree(u, +1);
  ChangeAns(u, +1);
}
long long sqr(long long x) { return x * x; }
double Query(int k) {
  long long ans = (sumHeight[k] * sumCount[k] - sumDist[k]) * sqr(c[k]);
  ans += 1LL * n * cost * cost;
  ans -= 2LL * c[k] * cost * sumHeight[k];
  return (double)ans / n;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> q >> cost;
  for (int i = 1; i <= n; ++i) cin >> b[i];
  for (int i = 2; i <= n; ++i) {
    int p;
    cin >> p;
    adj[p].push_back(i);
    adj[i].push_back(p);
  }
  for (int i = 1; i <= m; ++i) cin >> c[i];
  h[1] = 1;
  DFS(1);
  Centroid();
  for (int i = 1; i <= n; ++i) {
    Update(i, b[i]);
  }
  while (q--) {
    int t;
    cin >> t;
    if (t == 1) {
      int x, w;
      cin >> x >> w;
      Update(x, w);
    } else {
      int k;
      cin >> k;
      cout << fixed << setprecision(7) << Query(k) << '\n';
    }
  }
  return 0;
}
