在VScode 和 洛谷在线ide上都能跑样例,但是一交上去就RE。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rl register ll
const ll N = 1e5 + 10, M = N << 1;
ll n, m;
ll tot, ne[M], e[M], h[N], w[N];
ll son[N], id[N], cnt, nw[N], sz[N], dep[N], fa[N], top[N];
struct Tree
{
ll l, r;
ll add, sum;
}tr[N << 2];
inline void add(ll a, ll b)
{
ne[++tot] = h[a], h[a] = tot, e[tot] = b;
}
inline void dfs1(ll u, ll fath, ll depth)
{
dep[u] = depth, fa[u] = fath, sz[u] = 1;
for(rl i=h[u]; ~i; i = ne[i])
{
ll v = e[i];
if(v == fath) continue;
dfs1(v, u, depth + 1);
sz[u] += sz[v];
if(sz[son[u]] < sz[v]) son[u] = v;
}
}
inline void dfs2(ll u, ll t)
{
id[u] = ++ cnt, nw[cnt] = w[u], top[u] = t;
if(!son[u]) return ;
dfs2(son[u], t);
for(rl i=h[u]; ~i; i = ne[i])
{
ll v = e[i];
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
inline void pushup(ll u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
inline void pushdown(ll u)
{
auto &root = tr[u], &l = tr[u << 1], &r = tr[u << 1 | 1];
if(root.add)
{
l.add += root.add, l.sum += root.add * (l.r - l.l + 1);
r.add += root.add, r.sum += root.add * (r.r - r.l + 1);
root.add = 0;
}
}
inline void build(ll u, ll l, ll r)
{
tr[u] = {l, r, 0, nw[r]};
if(l == r) return ;
ll mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
inline void update(ll u, ll l, ll r, ll k)
{
if(l <= tr[u].l && r >= tr[u].r)
{
tr[u].add += k;
tr[u].sum += k * (tr[u].r - tr[u].l + 1);
return ;
}
ll mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) update(u << 1, l, r, k);
if(r > mid) update(u << 1 | 1, l, r, k);
pushup(u);
}
inline ll query(ll u, ll l, ll r)
{
if(l <= tr[u].l && r >= tr[u].r) return tr[u].sum;
pushdown(u);
ll mid = tr[u].l + tr[u].r >> 1;
ll res = 0;
if(l <= mid) res += query(u << 1, l, r);
if(r > mid) res += query(u << 1 | 1, l, r);
return res;
}
inline void upd_point(ll u, ll k)
{
update(u, id[u], id[u], k);
}
inline void upd_tree(ll u, ll k)
{
update(u, id[u], id[u] + sz[u] - 1, k);
}
inline ll que_path(ll u)
{
ll res = 0, v = 1;
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
res += query(1, id[top[u]], id[u]);
u = fa[top[u]];
}
if(dep[u] < dep[v]) swap(v, u);
res += query(1, id[v], id[u]);
return res;
}
int main()
{
// freopen("1.in", "r", stdin), freopen("1.out", "w", stdout);
cin >> n >> m;
for(rl i=1; i <= n; ++ i) cin >> w[i];
memset(h, -1, sizeof h);
for(rl i=1; i < n; ++ i)
{
ll a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
dfs1(1, -1, 1);
dfs2(1, 1);
build(1, 1, n);
while(m -- )
{
ll t, u, k;
cin >> t >> u;
if(t == 1) { cin >> k; upd_point(u, k); }
else if(t == 2) {cin >> k, upd_tree(u, k); }
else {cout << que_path(u) << endl;}
}
return 0;
}