xxxxxxxb @ 2023-08-30 13:23:34
只过了#1#2#3#11,应该不是取模的问题
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = (int)1e5+7;
int n,m,r,MOD,a[N],fa[N],dfn[N],dep[N],siz[N],son[N],top[N],rks[N],cnt,bot[N];
std::vector<int> e[N];
void dfs_fi(int u,int depth) {
dep[u] = depth,siz[u] = 1;
for(auto v : e[u]) {
if(!dep[v]) {
fa[v] = u;
dfs_fi(v,depth+1);
siz[u] += siz[v];
son[u] = siz[son[u]] < siz[v] ? v : son[u];
}
}
}
void dfs_se(int u,int t) {
dfn[u] = ++cnt,top[u] = t;
rks[cnt] = u;
if(!son[u]) {
bot[u] = cnt;
return;
}
dfs_se(son[u],t);
for(auto v : e[u]) {
if(v!=fa[u]&&v!=son[u]) dfs_se(v,v);
}
bot[u] = cnt;
}
struct Segment_Tree {
int d[N<<2],b[N<<2];
int lson(int p) {return p << 1;}
int rson(int p) {return p << 1 | 1;}
int gm(int s,int t) {return (s+t)>>1;}
void pushup(int p) {
d[p] = (1ll*d[lson(p)]%MOD + d[rson(p)]%MOD)%MOD;
}
void pushd(int s,int t,int p) {
int m = gm(s,t);
if(b[p]) {
d[lson(p)] = (1ll*d[lson(p)]%MOD + 1ll*(m-s+1)*b[p]%MOD)%MOD;
d[rson(p)] = (1ll*d[rson(p)]%MOD + 1ll*(t-m)*b[p]%MOD)%MOD;
b[lson(p)] = (1ll*b[lson(p)]%MOD + 1ll*b[p]%MOD) % MOD;
b[rson(p)] = (1ll*b[rson(p)]%MOD + 1ll*b[p]%MOD) % MOD;
b[p] = 0;
}
}
void build(int s,int t,int p) {
if(s==t) {
d[p] = a[rks[s]];
return;
}
int m = gm(s,t);
build(s,m,lson(p));
build(m+1,t,rson(p));
pushup(p);
}
void upt(int s,int t,int p,int l,int r,int k) {
if(l<=s&&t<=r) {
d[p] = (1ll*d[p] + 1ll*(t-s+1)*k%MOD)%MOD;
b[p] = (1ll*b[p] + k%MOD) % MOD;
return;
}
int m = gm(s,t);
pushd(s,t,p);
if(l <= m) upt(s,m,lson(p),l,r,k);
if(r > m) upt(m+1,t,rson(p),l,r,k);
pushup(p);
}
int query(int s,int t,int p,int l,int r) {
if(l <= s&&t <= r) {
return d[p];
}
int m = gm(s,t),res = 0;
pushd(s,t,p);
if(l <= m) res = (1ll*res%MOD + query(s,m,lson(p),l,r)%MOD) % MOD;
if(r > m) res = (1ll*res%MOD + query(m+1,t,rson(p),l,r)%MOD) % MOD;
return res;
}
} tree;
auto que(int s,int t) -> int {
int res = 0;
while(top[s] != top[t]) {
if(dep[top[s]] < dep[top[t]]) swap(s,t);
res = (1ll*res%MOD + 1ll*tree.query(1,n,1,dfn[s],dfn[top[s]])%MOD)%MOD;
s = fa[top[s]];
}
if(dep[s] > dep[t]) swap(s,t);
res = (1ll*res%MOD + 1ll*tree.query(1,n,1,dfn[s],dfn[t])%MOD) % MOD;
return res%MOD;
}
auto add(int s,int t,int k) -> void {
while(top[s] != top[t]) {
if(dep[top[s]] < dep[top[t]]) swap(s,t);
tree.upt(1,n,1,dfn[s],dfn[top[s]],k);
s = fa[top[s]];
}
if(dep[s] > dep[t]) swap(s,t);
tree.upt(1,n,1,dfn[s],dfn[t],k);
}
void sol() {
int opt;
cin >> opt;
if(opt == 1) {
int x,y,z;
cin >> x >> y >> z;
add(x,y,z%MOD);
} else if(opt == 2) {
int x,y;
cin >> x >> y;
cout << que(x,y)%MOD << "\n";
} else if(opt == 3) {
int x,z;
cin >> x >> z;
tree.upt(1,n,1,dfn[x],dfn[x]+siz[x]-1,z);
} else {
int x;
cin >> x;
cout << tree.query(1,n,1,dfn[x],dfn[x]+siz[x]-1)%MOD << "\n";
}
}
signed main() {
//freopen("P3384_4.in","r",stdin);
cin.tie(0)->sync_with_stdio(0);
cin >> n >> m >> r >> MOD;
for(int i = 1;i <= n;++i) {
cin >> a[i];
}
for(int i = 1;i <= n-1;++i) {
int u,v;
cin >> u >> v;
e[u].push_back(v),e[v].push_back(u);
}
dfs_fi(r,1);
dfs_se(r,r);
tree.build(1,n,1);
while(m--) {
sol();
}
return 0;
}
by xxxxxxxb @ 2023-09-28 22:26:04
在一个节点跳到它的链顶的时候
dfs序较小的是链顶节点而非当前节点