ben090302 @ 2023-01-07 13:24:04
数据点1 3 4过了,其他的提示在xx行无输出,是树状数组写法,调了半天没调出来,求救
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=100010;
struct gr{//链式前向星存图
int to,nxt;
}g[maxn*2];
int tot,head[maxn],c[maxn],t[maxn];
int fa[maxn],dep[maxn],son[maxn],siz[maxn],top[maxn],dfn[maxn],w[maxn],tim,v[maxn];
void adeg(int u,int v){
g[++tot].to=v;
g[tot].nxt=head[u];
head[u]=tot;
}
int n,m,r,p;
int lb(int x){
return x&(-x);
}
void build(){
for(int i=1;i<=n;i++){
int prt=w[i]-w[i-1];
c[i]+=prt,t[i]+=prt*(i-1);
if(i+lb(i)<=n) c[i+lb(i)]+=c[i],t[i+lb(i)]+=t[i];
}
}
void add(int x,int k){
for(int i=x;i<=n;i+=lb(i))c[i]+=k,t[i]+=k*(x-1);
}
int query(int x){
int ret=0;
for(int i=x;i;i-=lb(i)) ret+=x*c[i]-t[i],ret%=p;
return (ret+p)%p;
}
void dfs1(int u,int f){//u=当前节点,f=u的跌
fa[u]=f;
dep[u]=dep[f]+1;
siz[u]=1;
int msize=-1;
for(int i=head[u];i;i=g[i].nxt){
int v=g[i].to;
if(v==f) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>msize){
msize=siz[v];
son[u]=v;
}
}
}
void dfs2(int u,int tp){//u为当前节点,t为当前链的顶端
dfn[u]=++tim;
top[u]=tp;
w[tim]=v[u];
if(!son[u]) return;
dfs2(son[u],tp);
for(int i=head[u];i;i=g[i].nxt){
int v=g[i].to;
if(v==fa[u] or v==son[u]) continue;
dfs2(v,v);
}
}
void mson(int x,int z){//修改子树 操作3
add(dfn[x],z);
add(dfn[x]+siz[x],-z);
}
int qson(int x){//查询子树 操作4
return (query(dfn[x]+siz[x]-1)-query(dfn[x]-1)+p)%p;
}
void mline(int x,int y,int z){//修改x到y最短路径 操作1
z%=p;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(dfn[top[x]],z),add(dfn[x]+1,-z);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
add(dfn[x],z),add(dfn[y]+1,-z);
}
int qline(int x,int y){//查询x到y最短路径 操作2
int ret=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=query(dfn[x])-query(dfn[top[x]]-1);
ret%=p;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ret+=query(dfn[y])-query(dfn[x]-1);
return (ret+p)%p;
}
signed main(){
cin>>n>>m>>r>>p;
for(int i=1;i<=n;i++) cin>>v[i];
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
adeg(u,v),adeg(v,u);
}
dfs1(r,r),dfs2(r,r);
build();//树状数组预处理
while(m--){
int mt,x,y,z;
cin>>mt;
if(mt==1) cin>>x>>y>>z,mline(x,y,z);
else if(mt==2) cin>>x>>y,cout<<qline(x,y)<<"\n";
else if(mt==3) cin>>x>>z,mson(x,z);
else cin>>x,cout<<qson(x)<<"\n";
}
}
by ben090302 @ 2023-01-08 08:06:52
取模出锅,此贴结