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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | #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; } |