Auto_Accepted @ 2023-09-23 09:20:06
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int tree[N << 2] , tag[N << 2];
int cnt , dep[N] , siz[N] , son[N] , fa[N] , top[N] , id[N] , w[N] , n , m , r , mod;
vector <int> a[N];
inline void pushup(int k){
tree[k] = tree[k << 1] + tree[k << 1 | 1];
tree[k] %= mod;
}
inline void pushdown(int k , int l , int r){
if(tag[k]){
tag[k << 1] += tag[k];
tag[k << 1 | 1] += tag[k];
int m = (l + r) >> 1;
tree[k << 1] += (m - l + 1) * tag[k];
tree[k << 1] %= mod;
tree[k << 1 | 1] += (r - m) * tag[k];
tree[k << 1 | 1] %= mod;
tag[k] = 0;
}
}
inline void update(int l , int r , int v , int s , int t , int p){
if(l <= s && t <= r){
tree[p] += (t - s + 1) * v;
tree[p] %= mod;
tag[p] += v;
tag[p] %= mod;
return;
}
pushdown(p , s , t);
int m = (s + t) >> 1;
if(l <= m) update(l , r , v , s , m , p << 1);
if(r > m) update(l , r , v , m + 1 , t , p << 1 | 1);
pushup(p);
}
inline int getsum(int l , int r , int s , int t , int p){
if(l <= s && t <= r){
return tree[p];
}
pushdown(p , s , t);
int m = (s + t) >> 1 , ans = 0;
if(l <= m) ans += getsum(l , r , s , m , p << 1) , ans %= mod;
if(r > m) ans += getsum(l , r , m + 1 , t , p << 1 | 1) , ans %= mod;
return ans;
}
inline void dfs1(int now , int f){
fa[now] = f;
siz[now] = 1;
dep[now] = dep[f] + 1;
int maxn = -1;
for(auto v : a[now]){
if(v == f) continue;
dfs1(v , now);
if(maxn < siz[v]){
maxn = siz[v];
son[now] = v;
}
siz[now] += siz[v];
}
}
inline void update(int u , int v , int k){
k %= mod;
update(u , v , k , 1 , n , 1);
}
inline int getsum(int u , int v){
return getsum(u , v , 1 , n , 1) % mod;
}
inline void dfs2(int now , int Top){
top[now] = Top;
id[now] = ++cnt;
if(w[now]){
update(id[now] , id[now] , w[now]);
}
if(!son[now]) return ;
dfs2(son[now] , Top);
for(auto v : a[now]){
if(v == fa[now] || v == son[now]) continue;
dfs2(v , v);
}
}
inline void update1(int u , int v , int k){
k %= mod;
while(top[u] != top[v]){
if(dep[u] < dep[v]) swap(u , v);
update(id[top[u]] , id[u] , k);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u , v);
update(id[u] , id[v] , k);
}
inline int query1(int u , int v){
int ans = 0;
while(top[u] != top[v]){
if(dep[u] < dep[v]) swap(u , v);
ans += getsum(id[top[u]] , id[u]);
ans %= mod;
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u , v);
ans += getsum(id[u] , id[v]);
ans %= mod;
return ans;
}
inline void update2(int now , int k){
k %= mod;
update(id[now] , id[now] + siz[now] - 1 , k);
}
inline int query2(int now){
return getsum(id[now] , id[now] + siz[now] - 1) % mod;
}
signed main(){
cin >> n >> m >> r >> mod;
for(int i = 1;i <= n;i++){
cin >> w[i];
}
for(int i = 1;i < n;i++){
int u , v;
cin >> u >> v;
a[u].push_back(v);
a[v].push_back(u);
}
dfs1(r , 0);
dfs2(r , r);
int op , x , y , z;
while(m--){
cin >> op;
if(op == 1){
cin >> x >> y >> z;
update1(x , y , z);
}
if(op == 2){
cin >> x >> y;
cout << query1(x , y) << endl;
}
if(op == 3){
cin >> x >> z;
update2(x , z);
}
if(op == 4){
cin >> x;
cout << query2(x) << endl;
}
}
}
by Auto_Accepted @ 2023-09-23 09:36:35
A了,少打了个 top
,此帖结