This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_subtree_sum"
#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
template <class T>
using V = vector<T>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll MOD = 998244353LL;
constexpr int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
template <class T>
void chmin(T &a, T b) { a = min(a, b); }
template <class T>
void chmax(T &a, T b) { a = max(a, b); }
void debug() { cerr << "ok" << endl; }
template <class T>
void printv(const vector<T> &v) {
for (int i = 0; i < v.size(); i++) cout << v[i] << (i + 1 == v.size() ? '\n' : ' ');
}
template <class T>
void readv(vector<T> &v) {
for (int i = 0; i < v.size(); i++) cin >> v[i];
}
#define call_from_test
#include "../DataStructure/BinaryIndexedTree.cpp"
#include "../Graph/HeavyLightDecomposition.cpp"
#undef call_from_test
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, q;
cin >> n >> q;
V<ll> a(n);
readv(a);
HLD g(n);
for (int i = 1; i < n; i++) {
int p;
cin >> p;
g.addedge(p, i);
}
BinaryIndexedTree<ll> bit(n);
for (int i = 0; i < n; i++) {
bit.add(g.index(i), a[i]);
}
while (q--) {
int t, u, v;
cin >> t >> u;
if (t == 0) {
cin >> v;
bit.add(g.index(u), v);
} else {
ll res = 0;
auto f = [&](int a, int b) { res += bit.get(a, b); };
g.getsubtree(u, f);
cout << res << '\n';
}
}
}
#line 1 "Test/HLDsubtree.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_subtree_sum"
#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
template <class T>
using V = vector<T>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll MOD = 998244353LL;
constexpr int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
template <class T>
void chmin(T &a, T b) { a = min(a, b); }
template <class T>
void chmax(T &a, T b) { a = max(a, b); }
void debug() { cerr << "ok" << endl; }
template <class T>
void printv(const vector<T> &v) {
for (int i = 0; i < v.size(); i++) cout << v[i] << (i + 1 == v.size() ? '\n' : ' ');
}
template <class T>
void readv(vector<T> &v) {
for (int i = 0; i < v.size(); i++) cin >> v[i];
}
#define call_from_test
#line 1 "DataStructure/BinaryIndexedTree.cpp"
//@docs Docs/BinaryIndexedTree.md
template <class T>
struct BinaryIndexedTree {
int n;
vector<T> dat;
BinaryIndexedTree(const int &n) : n(n + 1), dat(n + 1) {}
void add(int k, const T &x) {
for (++k; k < n; k += k & -k) dat[k] += x;
}
T get(int k) {
T res = 0;
for (++k; k > 0; k -= k & -k) res += dat[k];
return res;
}
inline T get(const int &l, const int &r) { //0-indexed [l,r)
return get(r - 1) - get(l - 1);
}
};
#line 1 "Graph/HeavyLightDecomposition.cpp"
//@docs Docs/HeavyLightDecomposition.md
struct HLD {
int n;
vector<vector<int>> G;
vector<int> sz, rt, id, par, out;
int pos, cnt;
HLD(int n) : n(n), G(n), sz(n, 1), rt(n, -1), id(n), par(n, -1), out(n), cnt(0) {}
void addedge(const int &u, const int &v) {
G[u].emplace_back(v);
G[v].emplace_back(u);
cnt++;
if (cnt == n - 1) {
build();
}
}
void build() {
szdfs(0, -1);
id[0] = 0;
rt[0] = 0;
pos = 0;
hld(0, -1);
}
void szdfs(int i, int p) {
for (auto &e : G[i]) {
if (e == p) continue;
szdfs(e, i);
par[e] = i;
sz[i] += sz[e];
if (sz[e] > sz[G[i][0]]) {
swap(G[i][0], e);
}
}
}
void hld(int i, int p) {
id[i] = pos;
pos++;
for (auto &e : G[i]) {
if (e == p) continue;
if (e == G[i][0]) {
rt[e] = rt[i];
} else {
rt[e] = e;
}
hld(e, i);
}
out[i] = pos;
}
template <class F>
void getpath_v(int u, int v, const F &f) { //f:[a,b)
while (1) {
if (id[u] > id[v]) swap(u, v);
if (rt[u] == rt[v]) {
f(id[u], id[v] + 1);
break;
} else {
f(id[rt[v]], id[v] + 1);
v = par[rt[v]];
}
}
}
template <class F>
void getpath_e(int u, int v, const F &f) { //f:[a,b)
while (1) {
if (id[u] > id[v]) swap(u, v);
if (rt[u] == rt[v]) {
if (u != v) f(id[u] + 1, id[v] + 1);
break;
} else {
f(id[rt[v]], id[v] + 1);
v = par[rt[v]];
}
}
}
template <class F>
void getsubtree(const int &u, const F &f) { //f:[a,b)
f(id[u], out[u]);
}
inline int index(const int &i) {
return id[i];
}
};
#line 32 "Test/HLDsubtree.test.cpp"
#undef call_from_test
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, q;
cin >> n >> q;
V<ll> a(n);
readv(a);
HLD g(n);
for (int i = 1; i < n; i++) {
int p;
cin >> p;
g.addedge(p, i);
}
BinaryIndexedTree<ll> bit(n);
for (int i = 0; i < n; i++) {
bit.add(g.index(i), a[i]);
}
while (q--) {
int t, u, v;
cin >> t >> u;
if (t == 0) {
cin >> v;
bit.add(g.index(u), v);
} else {
ll res = 0;
auto f = [&](int a, int b) { res += bit.get(a, b); };
g.getsubtree(u, f);
cout << res << '\n';
}
}
}