You have a root tree containing n vertexes. Let’s number the tree vertexes with integers from 1 to n. The tree root is in the vertex 1.
Each vertex (except fot the tree root) v has a direct ancestor p v. Also each vertex v has its integer value s v.
Your task is to perform following queries:
- P v u ( u ≠ v). If u isn’t in subtree of v, you must perform the assignment p v = u. Otherwise you must perform assignment p u = v. Note that after this query the graph continues to be a tree consisting of n vertexes.
- V v t. Perform assignment s v = t.
Your task is following. Before starting performing queries and after each query you have to calculate expected value written on the lowest common ancestor of two equiprobably selected vertices i and j. Here lowest common ancestor of i and j is the deepest vertex that lies on the both of the path from the root to vertex i and the path from the root to vertex j. Please note that the vertices i and j can be the same (in this case their lowest common ancestor coincides with them).
Input
The first line of the input contains integer n (2 ≤ n ≤ 5·104) — the number of the tree vertexes.
The second line contains n - 1 integer p 2, p 3, …, p n (1 ≤ p i ≤ n) — the description of the tree edges. It is guaranteed that those numbers form a tree.
The third line contains n integers — s 1, s 2, … s n (0 ≤ s i ≤ 106) — the values written on each vertex of the tree.
The next line contains integer q (1 ≤ q ≤ 5·104) — the number of queries. Each of the following q lines contains the description of the query in the format described in the statement. It is guaranteed that query arguments u and v lie between 1 and n. It is guaranteed that argument t in the queries of type V meets limits 0 ≤ t ≤ 106.
Output
Print q + 1 number — the corresponding expected values. Your answer will be considered correct if its absolute or relative error doesn’t exceed 10 - 9.
Examples
input
5
1 2 2 1
1 2 3 4 5
5
P 3 4
P 4 5
V 2 3
P 5 2
P 1 4
output
1.640000000
1.800000000
2.280000000
2.320000000
2.800000000
1.840000000
Note
Note that in the query P v u if u lies in subtree of v you must perform assignment p u = v. An example of such case is the last query in the sample.
Solution:
#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>
using namespace std;
const int N = 200010;
const int BLOCK = 350;
vector <int> g[N];
int pv[N];
int value[N];
long long coeff[N];
bool imp[N];
int down[N];
long long change[N], total[N];
int up[N];
long long sz[N];
int depth[N];
long long ans;
void dfs(int v) {
coeff[v] = 0;
sz[v] = 1;
down[v] = -1;
int only = -1;
for (int j = 0; j < (int)g[v].size(); j++) {
int u = g[v][j];
depth[u] = depth[v] + 1;
dfs(u);
sz[v] += sz[u];
coeff[v] -= sz[u] * sz[u];
if (down[u] != -1) {
if (down[v] == -1) {
down[v] = down[u];
only = u;
} else {
imp[v] = true;
}
}
}
if (imp[v]) {
down[v] = v;
}
coeff[v] += sz[v] * sz[v];
ans += value[v] * coeff[v];
if (!imp[v] && only != -1) {
change[v] = (sz[v] + 1) * (sz[v] + 1) - sz[v] * sz[v];
change[v] -= (sz[only] + 1) * (sz[only] + 1) - sz[only] * sz[only];
change[v] *= value[v];
} else {
change[v] = 0;
}
}
char op[N];
int arg1[N], arg2[N];
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
g[i].clear();
}
pv[1] = -1;
for (int i = 2; i <= n; i++) {
scanf("%d", pv + i);
g[pv[i]].push_back(i);
}
for (int i = 1; i <= n; i++) {
scanf("%d", value + i);
}
int tt;
scanf("%d", &tt);
for (int qq = 1; qq <= tt; qq++) {
char ch = getchar();
while (ch != 'P' && ch != 'V') {
ch = getchar();
}
op[qq] = ch;
scanf("%d %d", arg1 + qq, arg2 + qq);
}
int next_q = 1;
while (next_q <= tt) {
int last_q = next_q + BLOCK - 1;
if (last_q > tt) {
last_q = tt;
}
for (int i = 1; i <= n; i++) {
imp[i] = false;
}
for (int qq = next_q; qq <= last_q; qq++) {
if (op[qq] == 'P') {
imp[arg1[qq]] = true;
imp[arg2[qq]] = true;
} else {
imp[arg1[qq]] = true;
}
}
ans = 0;
depth[1] = 0;
dfs(1);
for (int i = 1; i <= n; i++) {
up[i] = i;
total[i] = 0;
}
for (int i = 1; i <= n; i++) {
if (down[i] != -1) {
total[down[i]] += change[i];
if (depth[i] < depth[up[down[i]]]) {
up[down[i]] = i;
}
}
}
if (next_q == 1) {
printf("%.15lf\n", (double)(1.0 * ans / n / n));
}
for (int qq = next_q; qq <= last_q; qq++) {
if (op[qq] == 'P') {
int v = arg1[qq];
int u = arg2[qq];
int z = u;
while (z != v && z != -1) {
z = pv[up[z]];
}
if (z == v) {
swap(u, v);
}
{
int z = v;
while (z != -1) {
ans -= total[z] * sz[v];
int new_z = pv[up[z]];
if (new_z == -1) {
break;
}
ans -= coeff[new_z] * value[new_z];
coeff[new_z] -= sz[new_z] * sz[new_z];
sz[new_z] -= sz[v];
coeff[new_z] += sz[new_z] * sz[new_z];
if (up[z] != z) {
coeff[new_z] += sz[up[z]] * sz[up[z]];
sz[up[z]] -= sz[v];
coeff[new_z] -= sz[up[z]] * sz[up[z]];
} else {
if (z != v) {
coeff[new_z] += (sz[up[z]] + sz[v]) * (sz[up[z]] + sz[v]);
coeff[new_z] -= sz[up[z]] * sz[up[z]];
} else {
coeff[new_z] += sz[up[z]] * sz[up[z]];
}
}
ans += coeff[new_z] * value[new_z];
z = new_z;
}
}
{
ans -= coeff[u] * value[u];
coeff[u] -= sz[u] * sz[u];
sz[u] += sz[v];
coeff[u] += sz[u] * sz[u];
coeff[u] -= sz[v] * sz[v];
ans += coeff[u] * value[u];
}
{
int z = u;
while (z != -1) {
ans += total[z] * sz[v];
int new_z = pv[up[z]];
if (new_z == -1) {
break;
}
ans -= coeff[new_z] * value[new_z];
coeff[new_z] -= sz[new_z] * sz[new_z];
sz[new_z] += sz[v];
coeff[new_z] += sz[new_z] * sz[new_z];
if (up[z] != z) {
coeff[new_z] += sz[up[z]] * sz[up[z]];
sz[up[z]] += sz[v];
coeff[new_z] -= sz[up[z]] * sz[up[z]];
} else {
coeff[new_z] += (sz[up[z]] - sz[v]) * (sz[up[z]] - sz[v]);
coeff[new_z] -= sz[up[z]] * sz[up[z]];
}
ans += coeff[new_z] * value[new_z];
z = new_z;
}
}
pv[v] = u;
total[v] = 0;
up[v] = v;
} else {
int v = arg1[qq];
ans += (arg2[qq] - value[v]) * coeff[v];
value[v] = arg2[qq];
}
printf("%.15lf\n", (double)(1.0 * ans / n / n));
}
for (int i = 1; i <= n; i++) {
g[i].clear();
}
for (int i = 2; i <= n; i++) {
g[pv[i]].push_back(i);
}
next_q = last_q + 1;
}
return 0;
}