TheIceStar @ 2023-07-03 12:07:46
#include <bits/stdc++.h>
#define ll long long
#define F(i,a,b) for (int i=a; i<=b; i++)
#define F1(i,a,b) for (int i=a; i<b; i++)
#define pb push_back
using namespace std;
const int MN=1e5+5;
struct segt{
ll dat,add;
}tree[MN*4];
int N,M,R,P,size[MN],verw[MN],fa[MN],root,wson[MN],top[MN],dfn[MN],vistime,tnum,depth[MN],id[MN];
vector<int> G[MN];
void build(int p,int l,int r){
if(l==r){tree[p].dat=verw[id[l]]; return ;}
int mid=(l+r)>>1,A=p*2,B=p*2+1;
build(A,l,mid);
build(B,mid+1,r);
tree[p].dat=tree[A].dat+tree[B].dat;
}
void pdown(int p,int l,int r){
int mid=(l+r)>>1,A=p*2,B=p*2+1;
tree[A].add+=tree[p].add,tree[B].add+=tree[p].add;
tree[A].dat+=tree[p].add*(mid-l+1), tree[B].dat+=tree[p].add*(r-mid);
tree[A].dat%=P,tree[B].dat%=P;
tree[A].add%=P,tree[B].add%=P;
tree[p].add=0;
}
void change(int p,int l,int r,int cl,int cr,int cnum){
if(cl<=l&&r<=cr){tree[p].dat+=(l-r+1)*cnum; tree[p].add+=cnum; return ;}
int mid=(l+r)>>1,A=p*2,B=p*2+1;
pdown(p,l,r);
if(cl<=mid) change(A,l,mid,cl,cr,cnum);
if(cr>=mid+1) change(B,mid+1,r,cl,cr,cnum);
tree[p].dat=(tree[A].dat+tree[B].dat)%P;
}
ll ask(int p,int l,int r,int fl,int fr){
if(fl<=l && r<=fr) return tree[p].dat;
int mid=(l+r)>>1,A=p*2,B=p*2+1;
pdown(p,l,r);
ll res=0;
if(fl<=mid) res+=ask(A,l,mid,fl,fr);
if(fr>=mid+1) res+=ask(B,mid+1,r,fl,fr);
return res%P;
}
void dfs1(int u){
size[u]=1;
depth[u]=depth[fa[u]]+1;
for(auto v:G[u]) if(v!=fa[u]){
fa[v]=u;
dfs1(v);
size[u]+=size[v];
if(size[v]>size[wson[u]]) wson[u]=v;
}
}
void dfs2(int u,int frt){
dfn[u]=++vistime;
id[vistime]=u;
top[u]=frt;
if(wson[u]) dfs2(wson[u],frt);
for(auto v:G[u]) if(v!=fa[u] && v!=wson[u]) dfs2(v,v);
}
void apath(int s,int t,int cnum){
while(top[s]!=top[t]){
if(depth[top[s]]<depth[top[t]]) swap(s,t);
change(1,1,N,dfn[top[s]],dfn[s],cnum);
s=fa[top[s]];
}
if(depth[s]>depth[t]) swap(s,t);
change(1,1,N,dfn[s],dfn[t],cnum);
}
ll qpath(int s,int t){
ll res=0;
while(top[s]!=top[t]){
if(depth[top[s]]<depth[top[t]]) swap(s,t);
res=(ask(1,1,N,dfn[top[s]],dfn[s])+res)%P;
s=fa[top[s]];
}
if(depth[s]>depth[t]) swap(s,t);
res=(ask(1,1,N,dfn[s],dfn[t])+res)%P;
return res;
}
void ason(int x,int cnum){
change(1,1,N,dfn[x],dfn[x]+size[x]-1,cnum);
}
ll qson(int x){
return ask(1,1,N,dfn[x],dfn[x]+size[x]-1)%P;
}
int main(){
// freopen("qaq.in","r",stdin);
cin>>N>>M>>R>>P;
F(i,1,N) cin>>verw[i];
F(i,1,N-1) {int u,v;cin>>u>>v;G[u].pb(v),G[v].pb(u);}
dfs1(R);
dfs2(R,R);
build(1,1,N);
F(i,1,M){
int opt,x,y,z;
cin>>opt;
if(opt==1){
cin>>x>>y>>z;
apath(x,y,z);
} else if (opt==2){
cin>>x>>y;
cout<<qpath(x,y)<<endl;
} else if(opt==3){
cin>>x>>z;
ason(x,z);
} else if(opt==4){
cin>>x;
cout<<qson(x)<<endl;
}
}
return 0;
}
错误数据
8 10 6 623232
56 838 680 614 846 408 890 829
1 2
2 3
3 4
1 5
4 7
4 8
7 6
3 4 859
1 4 2 189
2 1 7
悬赏关注两个 谢谢大佬了
by Anli_li_father @ 2023-07-03 13:34:18
你change函数里第一行
tree[p].dat+=(l-r+1)*cnum
应该改为
tree[p].dat+=(r-l+1)*cnum
by TheIceStar @ 2023-07-03 16:46:13
Ohhh 谢谢,orz 抱歉现在才看到
by TheIceStar @ 2023-07-03 16:46:58
已关注