1
+ // one of the best problems I've seen so far
2
+ // SPOJ : INS14L
3
+ #include < bits/stdc++.h>
4
+ #define ll long long
5
+ #define ull unsigned long long
6
+ #define vi vector<ll>
7
+ #define pp pair<ll,ll>
8
+ #define mp make_pair
9
+ #define PI acos (-1.0 )
10
+ #define all (v ) v.begin(),v.end()
11
+ #define pb push_back
12
+ #define FOR (i,a,b ) for (i=a;i<b;i++)
13
+ #define FREV (i,a,b ) for (i=a;i>=b;i--)
14
+ #define SULL (n ) scanf(" %llu" , &n)
15
+ #define INF 1e18
16
+ #define MOD 1000000007
17
+
18
+ #ifndef ONLINE_JUDGE
19
+ #define gc getchar
20
+ #define pc putchar
21
+ #else
22
+ #define gc getchar_unlocked
23
+ #define pc putchar_unlocked
24
+ #endif
25
+
26
+ using namespace std ;
27
+
28
+ int read_int () {
29
+ char c = gc ();
30
+ while ((c < ' 0' || c > ' 9' ) && c != ' -' ) c = gc ();
31
+ int ret = 0 , neg = 0 ;
32
+ if (c == ' -' ) neg = 1 , c = gc ();
33
+ while (c >= ' 0' && c <= ' 9' ) {
34
+ ret = 10 * ret + c - 48 ;
35
+ c = gc ();
36
+ }
37
+ return neg ? -ret : ret;
38
+ }
39
+
40
+ ll read_ll () {
41
+ char c = gc ();
42
+ while ((c < ' 0' || c > ' 9' ) && c != ' -' ) c = gc ();
43
+ ll ret = 0 ;
44
+ int neg = 0 ;
45
+ if (c == ' -' ) neg = 1 , c = gc ();
46
+ while (c >= ' 0' && c <= ' 9' ) {
47
+ ret = 10 * ret + c - 48 ;
48
+ c = gc ();
49
+ }
50
+ return neg ? -ret : ret;
51
+ }
52
+
53
+ struct node {
54
+ vi adj;
55
+ };
56
+
57
+ vi start_time (100005 ), end_time(100005 ), subtree_size(100005 ), depth(100005 ), cumulative_depth(100005 ), parent(100005 );
58
+ vector<node> tree;
59
+ ll timer = 0 ;
60
+
61
+ void dfs (ll u) {
62
+ ll i, v, len = tree[u].adj .size ();
63
+ start_time[u] = ++timer;
64
+ subtree_size[u] = 1 ;
65
+ cumulative_depth[u] = depth[u];
66
+
67
+ FOR (i,0 ,len) {
68
+ v = tree[u].adj [i];
69
+ depth[v] = depth[u] + 1 ;
70
+ dfs (v);
71
+ subtree_size[u] += subtree_size[v];
72
+ cumulative_depth[u] += cumulative_depth[v];
73
+ }
74
+
75
+ end_time[u] = timer;
76
+ }
77
+
78
+ ll range_query (ll* t, ll n, ll l, ll r) {
79
+ ll sum=0 ;
80
+ for (l+=n, r+=n; l<r; l>>=1 , r>>=1 ) {
81
+ if (l & 1 )
82
+ sum = (sum + t[l++])%MOD;
83
+ if (r & 1 )
84
+ sum = (sum + t[--r])%MOD;
85
+ }
86
+ return sum;
87
+ }
88
+
89
+ void point_update (ll* t, ll n, ll index, ll key) {
90
+ index += n;
91
+ t[index] = (t[index] + key)%MOD;
92
+ for (; index>1 ; index>>=1 ) {
93
+ t[index>>1 ] = (t[index] + t[index^1 ])%MOD;
94
+ }
95
+ }
96
+
97
+ void range_update (ll* t, ll n, ll l, ll r, ll key) {
98
+ for (l+=n, r+=n; l<r; l>>=1 , r>>=1 ) {
99
+ if (l & 1 ) {
100
+ t[l] = (t[l] + key)%MOD;
101
+ l++;
102
+ }
103
+ if (r & 1 ) {
104
+ --r;
105
+ t[r] = (t[r] + key)%MOD;
106
+ }
107
+ }
108
+ }
109
+
110
+ ll point_query (ll* t, ll n, ll index) {
111
+ ll ans = 0 ;
112
+ for (index+=n; index > 0 ; index>>=1 ) {
113
+ ans = (ans + t[index])%MOD;
114
+ }
115
+ return ans;
116
+ }
117
+
118
+ int main () {
119
+ ll i,j,t,u,n,q,x,k,total;
120
+ n = read_ll ();
121
+
122
+ tree.resize (n+1 );
123
+ ll seg_tree1[2 *n+2 ], seg_tree2[2 *n+2 ], seg_tree3[2 *n+2 ];
124
+
125
+ FOR (i,0 ,2 *n+2 ) {
126
+ seg_tree1[i] = seg_tree2[i] = seg_tree3[i] = 0 ;
127
+ }
128
+ parent[1 ] = 0 ;
129
+ FOR (i,2 ,n+1 ) {
130
+ j = read_ll ();
131
+ tree[j].adj .pb (i);
132
+ parent[i] = j;
133
+ }
134
+ dfs (1 );
135
+ // FOR(i,1,n+1) {
136
+ // printf("i = %lld st = %lld et = %lld sz = %lld dep = %lld cdep = %lld\n", i,start_time[i],end_time[i],subtree_size[i],depth[i],cumulative_depth[i]);
137
+ // }
138
+ q = read_ll ();
139
+ FOR (i,0 ,q) {
140
+ t = read_ll ();
141
+ u = read_ll ();
142
+
143
+ if (t == 1 ) {
144
+ x = read_ll ();
145
+ k = read_ll ();
146
+
147
+ total = subtree_size[u] * x + k * (cumulative_depth[u] - depth[u] * subtree_size[u]);
148
+ // printf("calculated total = %lld\n", total);
149
+ range_update (seg_tree1, n+1 , start_time[u], end_time[u]+1 , (x - (depth[u]*k) + MOD)%MOD);
150
+ range_update (seg_tree2, n+1 , start_time[u], end_time[u]+1 , k);
151
+ point_update (seg_tree3, n+1 , start_time[parent[u]], total);
152
+ // cout<<"==========================================================\n";
153
+ // FOR(j,1,2*n+2) {
154
+ // cout<<seg_tree1[j]<<" ";
155
+ // }
156
+ // cout<<"\n==========================================================\n";
157
+ // cout<<"==========================================================\n";
158
+ // FOR(j,1,2*n+2) {
159
+ // cout<<seg_tree2[j]<<" ";
160
+ // }
161
+ // cout<<"\n==========================================================\n";
162
+ // cout<<"==========================================================\n";
163
+ // FOR(j,1,2*n+2) {
164
+ // cout<<seg_tree3[j]<<" ";
165
+ // }
166
+ // cout<<"\n==========================================================\n";
167
+ }
168
+ else {
169
+ ll val1 = (point_query (seg_tree1, n+1 , start_time[u]) * subtree_size[u])%MOD;
170
+ ll val2 = (point_query (seg_tree2, n+1 , start_time[u]) * cumulative_depth[u])%MOD;
171
+ ll val3 = range_query (seg_tree3, n+1 , start_time[u], end_time[u]+1 );
172
+ // printf("val1 = %lld val2 = %lld val3 = %lld\n", val1, val2, val3);
173
+ total = ((val1 + val2)%MOD + val3)%MOD;
174
+ if (total < 0 )
175
+ total += MOD;
176
+
177
+ printf (" %lld\n " , total);
178
+ }
179
+ }
180
+ return 0 ;
181
+ }
0 commit comments