自己实在找不到错了 请大佬看看哪里有问题,谢谢!
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,root,mod;
int idx=1;
int ans1=0,ans2=0;
struct node{
int l;
int r;
int sum;
int lazy;
}tree[4*N];
int head[N],ver[2*N],nex[2*N],son[N],size[N],f[N],d[N],top[N],id[N],rk[N];
int input[N];
int cnt=1;
void add_e(int x,int y){
ver[++idx]=y;
nex[idx]=head[x];
head[x]=idx;
}
void build(int l,int r,int i){//常规建树
tree[i].l=l;
tree[i].r=r;
if(l==r){
tree[i].sum=input[i]%mod;
return ;
}
int mid=(l+r)/2;
build(l,mid,2*i);
build(mid+1,r,2*i+1);
tree[i].sum=(tree[2*i].sum+tree[2*i+1].sum)%mod;
}
void push_down(int i){//延迟标记下移
if(tree[i].lazy){
tree[i].sum+=(tree[i].r-tree[i].l+1)* tree[i].lazy;
tree[2*i].lazy+=tree[i].lazy;
tree[2*i+1].lazy+=tree[i].lazy;
tree[i].lazy=0;
}
}
int ask(int i,int L,int R){//区间查询
if(tree[i].l>=L&&tree[i].r<=R) return tree[i].sum;
if(tree[i].lazy)push_down(i);
int mid=(tree[i].l+tree[i].r)/2;
if(mid>=L) ans1+=ask(2*i,L,R);
if(mid<=R) ans1+=ask(2*i+1,L,R);
return ans1%mod;
}
void add(int i,int L,int R,int k){//区间修改
if(tree[i].l>=L&&tree[i].r<=R){
tree[i].sum+=(tree[i].r-tree[i].l+1)*k;
tree[i].lazy+=k;
return ;
}
push_down(i);
int mid=(tree[i].l+tree[i].r)/2;
if(mid>=L) add(2*i,L,R,k);
if(mid<=R) add(2*i+1,L,R,k);
}
void dfs1(int x,int fa,int depth){//x:当前结点 fa:父结点 depth:当前结点深度
f[x]=fa;//更新父结点
d[x]=depth;//更新深度
size[x]=1;//子树大小初始化:根节点本身
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(y==fa) return ;
dfs1(y,x,depth+1);
if(size[y]>size[son[x]]) son[x]=y;//更新重儿子
size[x]+=size[y];//更新子树大小
}
return ;
}
void dfs2(int u,int t){//u为当前结点,t为链段
top[u]=t;
id[u]=++cnt;
rk[cnt]=u;//新的编号
if(!son[u]) return ;
dfs2(son[u],t);//优先遍历重儿子,使一条链上编号连续
for(int i=head[u];i;i=nex[i]){
int y=ver[i];
if(y==son[u]||y==f[u]) continue;
dfs2(y,y);//再建一条链
}
}
void func1(int x,int y,int k){//将树从 x到 y结点最短路径上所有节点的值都加上k
while(top[x]!=top[y]){//循环,直到这两个点处于同一条链
if(d[top[x]]<d[top[y]]) swap(x,y);//规范
add(1,id[x],id[top[x]],k);
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);//深度较浅的一定是序号较小的
add(1,id[x],id[y],k);
}
void func2(int x,int y){
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
ans2+=ask(1,id[x],id[top[x]]);
ans1=0;
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);//道理同上
ans2+=ask(1,id[x],id[y]);
ans1=0;
}
int main(){
cin>>n>>m>>root>>mod;
for(int i=1;i<=n;i++){
cin>>input[i];//输入节点初始值
}
for(int i=1;i<=n-1;i++){
int x,y;
cin>>x>>y;
add_e(x,y);
add_e(y,x);//建图
}
dfs1(root,0,1);//第一次dfs求son,depth,f,size
dfs2(root,root);//第二次dfs求id,rk,将树拆成链表
build(1,n,1);//建树
for(int i=1;i<=m;i++){
int type;
cin>>type;
if(type==1){
int x,y,z;
cin>>x>>y>>z;
func1(x,y,z);
}
if(type==2){
int x,y;
cin>>x>>y;
func2(x,y);
cout<<ans2<<endl;
ans2=0;
}
if(type==3){
int x,z;
cin>>x>>z;
func1(id[x],id[x]+size[x]-1,z);
}
if(type==4){
int x;
cin>>x;
func2(id[x],id[x]+size[x]-1);
cout<<ans2<<endl;
ans2=0;
}
}
return 0;
}