wanghaolin44243787 @ 2024-08-07 20:51:39
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 100005
ll n, m, r, mod, a[MAXN], ans[MAXN << 2], tag[MAXN << 2], id[MAXN], x, y, z, w, tot[MAXN], fa[MAXN], top[MAXN], dep[MAXN], son[MAXN], cnt, v[MAXN], t;
vector<ll>edge[MAXN];
inline void dfs1(ll now, ll f, ll dp) {
fa[now] = f;
dep[now] = dp;
tot[now] = 1;
ll maxson = -1;
for (int i = 0; i < edge[now].size(); i++) {
if (edge[now][i] == f) {
continue;
}
dfs1(edge[now][i], now, dp + 1);
tot[now] += tot[edge[now][i]];
if (maxson < max(tot[edge[now][i]], maxson)) {
maxson = max(tot[edge[now][i]], maxson);
son[now] = edge[now][i];
}
}
return;
}
inline void dfs2(ll now, ll topof) {
id[now] = ++cnt;
v[cnt] = a[now];
top[now] = topof;
if (son[now] == 0)return;
dfs2(son[now], topof);
for (int i = 0; i < edge[now].size(); i++) {
if (id[edge[now][i]] == 0) {
dfs2(edge[now][i], edge[now][i]);
}
}
return;
}
inline void push_back(ll p, ll l, ll r) {
ll mid = l / 2.0 + r / 2.0;
ans[p * 2] += tag[p] * (l - mid + 1);
ans[p * 2] %= mod;
tag[p * 2] += tag[p];
tag[p * 2] %= mod;
ans[p * 2 + 1] += tag[p] * (r - mid);
ans[p * 2 + 1] %= mod;
tag[p * 2 + 1] += tag[p];
tag[p * 2 + 1] %= mod;
tag[p] = 0;
}
inline void build(ll p, ll l, ll r) {
if (l == r) {
ans[p] = v[l];
return;
}
ll mid = l / 2.0 + r / 2.0;
build(p * 2, l, mid);
build(p * 2 + 1, mid + 1, r);
ans[p] = ans[p * 2] + ans[p * 2 + 1];
ans[p] %= mod;
return;
}
inline void update(ll dl, ll dr, ll l, ll r, ll p, ll k) {
k %= mod;
if (dl <= l && dr >= r) {
ans[p] += k * (r - l + 1);
ans[p] %= mod;
tag[p] += k;
tag[p] %= mod;
return ;
}
ll mid = l / 2.0 + r / 2.0;
push_back(p, l, r);
if (dl <= mid)update(dl, dr, l, mid, p * 2, k);
if (dr > mid)update(dl, dr, mid + 1, r, p * 2 + 1, k);
ans[p] = ans[p * 2] + ans[p * 2 + 1];
ans[p] %= mod;
return;
}
ll query(ll dl, ll dr, ll l, ll r, ll p) {
if (dl <= l && dr >= r)return ans[p];
ll sum = 0;
ll mid = l / 2.0 + r / 2.0;
push_back(p, l, r);
if (dl <= mid) {
sum += query(dl, dr, l, mid, p * 2);
sum %= mod;
}
if (dr > mid) {
sum += query(dl, dr, mid + 1, r, p * 2 + 1);
sum %= mod;
}
return sum % mod;
}
inline void tree_update(ll a, ll b, ll c) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
update(id[top[a]], id[a], 1, n, 1, c);
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
update(id[x], id[y], 1, n, 1, c);
return;
}
ll tree_query(ll a, ll b) {
ll qq = 0;
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
qq += query(id[top[a]], id[a], 1, n, 1);
qq %= mod;
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
qq += query(id[x], id[y], 1, n, 1);
qq %= mod;
return qq % mod;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> r >> mod;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i < n; i++) {
cin >> x >> y;
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs1(r, 0, 1);
dfs2(r, r);
build(1, 1, n);
for (int i = 1; i <= m; i++) {
cin >> x;
if (x == 1) {
cin >> y >> z >> w;
tree_update(y, z, w);
} else if (x == 2) {
cin >> y >> z;
cout << tree_query(y, z) << "\n";
} else if (x == 3) {
cin >> y >> z;
update(id[y], id[y] + tot[y] - 1, 1, n, 1, z);
} else if (x == 4) {
cin >> y;
cout << query(id[y], id[y] + tot[y] - 1, 1, n, 1) % mod << "\n";
}
}
return 0;
}
by wanghaolin44243787 @ 2024-08-08 09:44:38
inline void tree_update(ll a, ll b, ll c) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
update(id[top[a]], id[a], 1, n, 1, c);
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
update(id[x], id[y], 1, n, 1, c);
return;
}
ll tree_query(ll a, ll b) {
ll qq = 0;
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
qq += query(id[top[a]], id[a], 1, n, 1);
qq %= mod;
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
qq += query(id[x], id[y], 1, n, 1);
qq %= mod;
return qq % mod;
}
改为
inline void tree_update(ll a, ll b, ll c) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
update(id[top[a]], id[a], 1, n, 1, c);
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
update(id[a], id[b], 1, n, 1, c);
return;
}
ll tree_query(ll a, ll b) {
ll qq = 0;
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
qq += query(id[top[a]], id[a], 1, n, 1);
qq %= mod;
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
qq += query(id[a], id[b], 1, n, 1);
qq %= mod;
return qq % mod;
}
by wanghaolin44243787 @ 2024-08-08 09:45:46
此贴结
by Eastern_Leaf @ 2024-08-08 11:49:02
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
by ChangeYuAN @ 2024-08-08 17:41:56
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%