rt,求调。
#include <iostream>
#include <stack>
#include <cmath>
#include <vector>
#include <map>
#include <string.h>
#include <queue>
#include <stdio.h>
#include <iomanip>
#include <cstdio>
#include <algorithm>
//#define int long long
using namespace std;
const int N = 1e6 + 10;
const int INF = 0x3f3f3f3f;
int n, m, r, p;
int head[N], ne[N], to[N], id;
void add(int x, int y)
{
to[++id] = y;
ne[id] = head[x];
head[x] = id;
}
int a[N], low[N];
struct node
{
int l, r, lz;
int sum;
}tr[N << 3];
int mod;
void push_up(int u)
{
tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum ) ;
}
void push_down(int u)
{
int lz = tr[u].lz;
if(!lz) return ;
tr[u << 1].lz += lz;
tr[u << 1 | 1].lz += lz;
(tr[u << 1].sum += (lz * (tr[u << 1].r - tr[u << 1].l + 1 ) ) ) ;
(tr[u << 1 | 1].sum += (lz * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1 ) ) ) ;
tr[u].lz = 0;
}
void build(int u, int l, int r)
{
tr[u].l = l, tr[u].r = r;
if(l == r)
{
tr[u].sum = a[low[l]] ;
return ;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
push_up(u);
}
int query(int u, int l, int r)
{
if(l <= tr[u].l && tr[u].r <= r)
{
return tr[u].sum;
}
push_down(u);
int ans = 0;
int mid = (tr[u].l + tr[u].r) >> 1;
if(l <= mid) (ans += query(u << 1, l, r) ) ;
if(mid < r) (ans += query(u << 1 | 1, l, r) ) ;
return ans ;
}
void update(int u, int l, int r, int k)
{
if(l <= tr[u].l && tr[u].r <= r)
{
tr[u].lz += k;
(tr[u].sum += ((k * (tr[u].r - tr[u].l + 1))));
return ;
}
int mid = (tr[u].l + tr[u].r) >> 1;
push_down(u);
if(l <= mid) update(u << 1, l, r, k);
if(mid < r) update(u << 1 | 1, l, r, k);
push_up(u);
}
int dep[N], fa[N], son[N], siz[N];
void dfs1(int u, int faa)
{
fa[u] = faa;
dep[u] = dep[faa] + 1;
siz[u] = 1;
int ms = -1;
for(int i = head[u]; i; i = ne[i])
{
int v = to[i];
if(v == faa) continue;
dfs1(v, u);
siz[u] += siz[v];
if(siz[v] > ms) son[u] = v, ms = siz[v];
}
}
int dfn[N], dn, top[N];
void dfs2(int u, int tp)
{
dfn[u] = ++dn;
top[u] = tp;
low[dn] = u;
if(!son[u]) return ;
dfs2(son[u], tp);
for(int i = head[u]; i; i = ne[i])
{
int v = to[i];
if(v == fa[u] || v == son[u]) continue;
dfs2(v,v);
}
}
int query_way(int x, int y)
{
int ans = 0;
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x, y);
(ans += query(1, dfn[top[x]], dfn[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
ans += query(1, dfn[x], dfn[y]);
return ans;
}
void add_way(int x, int y, int k)
{
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x, y);
update(1, dfn[top[x]], dfn[x], k);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
update(1, dfn[x], dfn[y], k);
}
int query_tree(int x)
{
return query(1, dfn[x], dfn[x] + siz[x] - 1);
}
void add_tree(int x, int k)
{
update(1, dfn[x] + 1, dfn[x] + siz[x] - 1, k);
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
// mod = 2147483647;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
if(i == 1) continue;
int x;
cin >> x;
add(i, x), add(x, i);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
while(m--)
{
char opt;
int x, y, z;
cin >> opt >> x;
if(opt == 'p')
{
cin >> y;
add_tree(x, y);
}
else
{
cout << query(1, dfn[x], dfn[x]) << endl;
}
}
return 0;
}