Skip to content

Commit 55b9159

Browse files
committed
Add submission for INS14L
1 parent 01ffd0c commit 55b9159

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

INS14L.cpp

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
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

Comments
 (0)