柠檬布丁吖 @ 2023-04-02 19:58:06
//inline void dfs1(int x,int f,int deep){
// dep[x]=deep;
// fa[x]=f;
// siz[x]=1;
// int maxson=-1;
// for(int i=beg[x];i;i=ne[i]){
// int y=to[i];
// if(y==f) continue;
// dfs1(y,x,deep+1);
// siz[x]+=siz[y];
// if(siz[y]>maxson) son[x]=y;maxson=siz[y];
// }
//}
//
//inline void dfs2(int x,int topf){
// id[x]=++cnt;
// wt[cnt]=w[x];
// top[x]=topf;
// if(!son[x]) return;
// dfs2(son[x],topf);
// for(int i=beg[x];i;i=ne[i]){
// int y=to[i];
// if(y==fa[x]||y==son[x]) continue;
// dfs2(y,y);
// }
//}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mid ((l+r)>>1)
#define len (r-l+1)
inline int read() {
int ret=0,f=1;
char c=getchar();
for(; c<'0'||c>'9'; c=getchar()) if(c=='-') c=getchar();
for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
return ret*f;
}
int n,m,r,mod;
const int maxn=2e6+55;
int e,beg[maxn],nex[maxn],to[maxn],w[maxn],wt[maxn];
int a[maxn<<2],laz[maxn<<2];
int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
int res=0;
inline void add(int x,int y) {
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void dfs1(int x,int f,int deep) {
dep[x]=deep;
fa[x]=f;
siz[x]=1;
int maxson=-1;
for(int i=beg[x]; i; i=nex[x]) {
int y=to[i];
if(y==f) continue;
dfs1(y,x,deep+1);
siz[x]+=siz[y];
if(siz[y]>maxson) son[x]=y;
maxson=siz[y];
}
}
inline void dfs2(int x,int topf) {
id[x]=++cnt;
wt[cnt]=w[x];
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(int i=beg[x]; i; i=nex[i]) {
int y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
inline void build(int rt,int l,int r) {
if(l==r) {
a[rt]=wt[l];
if(a[rt]>mod) a[rt]%=mod;
return;
}
build(rt<<1,l,mid);
build(rt<<1||1,mid+1,r);
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
void pushdown(int rt,int lenn) {
laz[rt<<1]+=laz[rt];
laz[rt<<1|1]+=laz[rt];
a[rt<<1]+=laz[rt]*(lenn-(lenn>>1));
a[rt<<1|1]+=laz[rt]*(lenn>>1);
a[rt<<1]%=mod;
a[rt<<1|1]%=mod;
laz[rt]=0;
}
inline void update(int rt,int l,int r,int L,int R,int k) {
if(L<=l&&r<=R) {
laz[rt]+=k;
a[rt]+=k*len;
} else {
if(laz[rt]) pushdown(rt,len);
if(L<=mid) update(rt<<1,l,mid,L,R,k);
if(R>mid) update(rt<<1|1,mid+1,r,L,R,k);
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
}
inline void uprange(int x,int y,int k) {
k%=mod;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,1,n,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,1,n,id[x],id[y],k);
}
inline void query(int rt,int l,int r,int L,int R) {
if(L<=l&&r<=R) {
res+=a[rt];
res%=mod;
return;
} else {
if(laz[rt]) pushdown(rt,len);
if(L<=mid) query(rt<<1,l,mid,L,R);
if(R>mid) query(rt<<1|1,mid+1,r,L,R);
}
}
inline int qrange(int x,int y) {
int ans=0;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=0;
query(1,1,n,id[top[x]],id[x]);
ans+=res;
ans%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
res=0;
query(1,1,n,id[x],id[y]);
ans+=res;
return ans%mod;
}
inline void upson(int x,int k) {
update(1,1,n,id[x],id[x]+siz[x]-1,k);
}
inline int qson(int x) {
res=0;
query(1,1,n,id[x],id[x]+siz[x]-1);
return res;
}
signed main(void) {
n=read();
m=read();
r=read();
mod=read();
for(int i=1; i<=n; i++) {
w[i]=read();
}
for(int i=1; i<n-1; i++) {
int a,b;
a=read();
b=read();
add(a,b);
add(b,a);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,1,n);
while(m--) {
int k,x,y,z;
k=read();
if(k==1) {
x=read();
y=read();
z=read();
uprange(x,y,z);
}
if(k==2) {
x=read();
y=read();
printf("%d\n",qrange(x,y));
}
if(k==3) {
x=read();
z=read();
upson(x,y);
}
if(k==4) {
x=read();
printf("%d\n",qson(x));
}
}
return 0;
}
by Lucky_Luo @ 2023-04-02 20:24:04
if(siz[y]>maxson) son[x]=y;
maxson=siz[y];
要写成
if(siz[y]>maxson)
{
son[x]=y;
maxson=siz[y];
}
by Lucky_Luo @ 2023-04-02 20:26:25
另外,操作3的参数传错了
by Lucky_Luo @ 2023-04-02 20:27:47
还有一些值更新之后没有取模
by 柠檬布丁吖 @ 2023-04-02 20:43:02
@Lucky_Luo
基本上改了一下。还是不行。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mid ((l+r)>>1)
#define len (r-l+1)
inline int read() {
int ret=0,f=1;
char c=getchar();
for(; c<'0'||c>'9'; c=getchar()) if(c=='-') c=getchar();
for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
return ret*f;
}
int n,m,r,mod;
const int maxn=2e6+55;
int e,beg[maxn],nex[maxn],to[maxn],w[maxn],wt[maxn];
int a[maxn<<2],laz[maxn<<2];
int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
int res=0;
inline void add(int x,int y) {
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void dfs1(int x,int f,int deep) {
dep[x]=deep;
fa[x]=f;
siz[x]=1;
int maxson=-1;
for(int i=beg[x]; i; i=nex[x]) {
int y=to[i];
if(y==f) continue;
dfs1(y,x,deep+1);
siz[x]+=siz[y];
if(siz[y]>maxson){
son[x]=y;maxson=siz[y];
}
}
}
inline void dfs2(int x,int topf) {
id[x]=++cnt;
wt[cnt]=w[x];
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(int i=beg[x]; i; i=nex[i]) {
int y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
inline void build(int rt,int l,int r) {
if(l==r) {
a[rt]=wt[l];
if(a[rt]>mod) a[rt]%=mod;
return;
}
build(rt<<1,l,mid);
build(rt<<1||1,mid+1,r);
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
void pushdown(int rt,int lenn) {
laz[rt<<1]+=laz[rt];
laz[rt<<1|1]+=laz[rt];
a[rt<<1]+=laz[rt]%mod*(lenn-(lenn>>1))%mod;
a[rt<<1|1]+=laz[rt]%mod*(lenn>>1)%mod;
a[rt<<1]%=mod;
a[rt<<1|1]%=mod;
laz[rt]=0;
}
inline void update(int rt,int l,int r,int L,int R,int k) {
if(L<=l&&r<=R) {
laz[rt]+=k;
a[rt]+=k*len%mod;
} else {
if(laz[rt]) pushdown(rt,len);
if(L<=mid) update(rt<<1,l,mid,L,R,k);
if(R>mid) update(rt<<1|1,mid+1,r,L,R,k);
a[rt]=(a[rt<<1]%mod+a[rt<<1|1]%mod)%mod;
}
}
inline void uprange(int x,int y,int k) {
k%=mod;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,1,n,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,1,n,id[x],id[y],k);
}
inline void query(int rt,int l,int r,int L,int R) {
if(L<=l&&r<=R) {
res+=a[rt];
res%=mod;
return;
} else {
if(laz[rt]) pushdown(rt,len);
if(L<=mid) query(rt<<1,l,mid,L,R);
if(R>mid) query(rt<<1|1,mid+1,r,L,R);
}
}
inline int qrange(int x,int y) {
int ans=0;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=0;
query(1,1,n,id[top[x]],id[x]);
ans=res%mod+ans%mod;
ans%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
res=0;
query(1,1,n,id[x],id[y]);
ans=res%mod+ans%mod;
return ans%mod;
}
inline void upson(int x,int k) {
update(1,1,n,id[x],id[x]+siz[x]-1,k);
}
inline int qson(int x) {
res=0;
query(1,1,n,id[x],id[x]+siz[x]-1);
return res%mod;
}
signed main(void) {
n=read();
m=read();
r=read();
mod=read();
for(int i=1; i<=n; i++) {
w[i]=read();
}
for(int i=1; i<n-1; i++) {
int a,b;
a=read();
b=read();
add(a,b);
add(b,a);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,1,n);
while(m--) {
int k,x,y,z;
k=read();
if(k==1) {
x=read();
y=read();
z=read();
uprange(x,y,z);
}
if(k==2) {
x=read();
y=read();
printf("%d\n",qrange(x,y));
}
if(k==3) {
x=read();
y=read();
upson(x,y);
}
if(k==4) {
x=read();
printf("%d\n",qson(x));
}
}
return 0;
}