链剖“板子”:
这板子会让你疯狂:
#include<bits/stdc++.h>
const int N=200000+5;
using namespace std;
int head[N<<2],nxt[N<<2],to[N<<2],cn;
long long sum[N<<2],tar[N<<2],flag[N<<2];
int a[N<<1],seq[N<<1],dep[N<<1],son[N<<1],fa[N<<1],siz[N<<1],in[N<<1],out[N<<1],top[N<<1];
int n,m,x,y,z,uu,vv,ok,mod,idc,root;
inline void read(int &x) {
int f=1;x=0;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=10*x+c-48,c=getchar();
x=x*f;
}
void update(int o){
sum[o]=(sum[o<<1|1]%mod+sum[o<<1]%mod)%mod;
}
void pushdown(int o,int l,int r){
if(flag[o]){
int mid=(l+r)>>1;
sum[o<<1]=(sum[o<<1]+1ll*(mid-l+1)*tar[o])%mod;
sum[o<<1|1]=(sum[o<<1|1]+1ll*(r-mid)*tar[o])%mod;
tar[o<<1]=(tar[o<<1]+tar[o])%mod;
tar[o<<1|1]=(tar[o<<1|1]+tar[o])%mod;
flag[o<<1]=flag[o<<1|1]=1;
tar[o]=flag[o]=0;
}
}
void build(int o,int l,int r){
if(l==r){
sum[o]=(1ll*a[seq[l]])%mod;
return ;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
update(o);
}
void modify(int o,int l,int r,const int L,const int R,const int val){
if(L<=l && r<=R){
sum[o]=(sum[o]+(1ll*(r-l+1)*val))%mod;
tar[o]=(tar[o]+val)%mod;
flag[o]=1;
return ;
}
pushdown(o,l,r);
int mid=(l+r)>>1;
if(L<=mid)
modify(o<<1,l,mid,L,R,val);
if(R>mid)
modify(o<<1|1,mid+1,r,L,R,val);
update(o);
}
long long query(int o,int l,int r,const int L,const int R){
if(L<=l && r<=R)
return sum[o]%mod;
int mid=(l+r)>>1;
long long ans=0;
pushdown(o,l,r);
if(L<=mid) ans=(ans+query(o<<1,l,mid,L,R))%mod;
if(R>mid) ans=(ans+query(o<<1|1,mid+1,r,L,R))%mod;
return ans%mod;
}
void create(int u,int v){
cn++;
to[cn]=v;
nxt[cn]=head[u];
head[u]=cn;
}
void dfs1(int u,int f){
int v;
siz[u]=1;
for(int i=head[u];i;i=nxt[i]){
v=to[i];
if(v==f) continue;
fa[v]=u;dep[v]=dep[u]+1;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int tp){
int v;
in[u]=++idc;
seq[idc]=u;
top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(int i=head[u];i;i=nxt[i]){
v=to[i];
if(v==fa[u] || v==son[u]) continue;
dfs2(v,v);
}
out[u]=idc;
}
long long query(int u,int v){
long long ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) u^=v^=u^=v;
ans=(ans+query(1,1,idc,in[top[u]],in[u]))%mod;//惨痛教训!!一定不能写成top[u];
u=fa[top[u]];
}
if(dep[u]<dep[v]) u^=v^=u^=v;
ans=(ans+query(1,1,idc,in[v],in[u]))%mod;
return ans%mod;
}
void modify(int u,int v,int val){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) u^=v^=u^=v;
modify(1,1,idc,in[top[u]],in[u],val);
u=fa[top[u]];
}
if(dep[u]<dep[v]) u^=v^=u^=v;
modify(1,1,idc,in[v],in[u],val);
}
int main(){
read(n);read(m);read(root);read(mod);
mod=1ll*mod;
for(int i=1;i<=n;i++)
read(a[i]);
for(int i=1;i<n;i++){
read(uu);read(vv);
create(uu,vv);
create(vv,uu);
}
fa[root]=root;
dep[root]=1;
dfs1(root,root);
dfs2(root,root);
build(1,1,idc);
for(int i=1;i<=m;i++){
read(ok);
if(ok==1){
read(x);read(y);read(z);
modify(x,y,z);
}
if(ok==2){
read(x);read(y);
printf("%lld\n",query(x,y));
}
if(ok==3){
read(x);read(z);
modify(1,1,idc,in[x],out[x],z);
}
if(ok==4){
read(x);
printf("%lld\n",query(1,1,idc,in[x],out[x]));
}
}
return 0;
}
链剖就是细节问题,没法;
AC;
校本课圆满了!