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