coolcoder @ 2023-07-10 21:38:04
刚学完树剖板子都调不出来,大佬救救
如是什么特别傻的错误轻喷
28pts提交记录
这是我的代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010,M=2*N;
ll n,m,root,mod;
ll h[N],e[M],ne[M],idx;
ll w[N],nw[N];
ll dep[N],top[N];
ll fa[N],sn[N],sz[N];
ll id[N],dfn;
ll read()
{
ll x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct Node
{
int l,r;
ll tag,sum;
}tr[N*4];
inline void adde(int u,int v)
{
e[idx]=v;
ne[idx]=h[u];
h[u]=idx++;
}
inline void dfs1(int u,int father,int depth)
{
dep[u]=depth,fa[u]=father,sz[u]=1;
for(int i=h[u];~i;i=ne[i])
{
int v=e[i];
if(v==father) continue;
dfs1(v,u,depth+1);
sz[u]+=sz[v];
if(sz[sn[u]]<sz[v]) sn[u]=v;
}
}
inline void dfs2(int u,int t)
{
id[u]=++dfn,nw[dfn]=w[u],top[u]=t;
if(!sn[u]) return;
dfs2(sn[u],t);
for(int i=h[u];~i;i=ne[i])
{
int v=e[i];
if(v==fa[u]||v==sn[u]) continue;
dfs2(v,v);
}
}
inline void pushup(int u)
{
tr[u].sum=(tr[u<<1].sum+tr[u<<1|1].sum)%mod;
}
inline void pushdown(int u)
{
if(tr[u].tag)
{
tr[u<<1].tag=(tr[u<<1].tag+tr[u].tag)%mod,tr[u<<1|1].tag=(tr[u<<1|1].tag+tr[u].tag)%mod;
tr[u<<1].sum=(tr[u<<1].sum+tr[u].tag*(tr[u<<1].r-tr[u<<1].l+1))%mod;
tr[u<<1|1].sum=(tr[u<<1|1].sum+tr[u].tag*(tr[u<<1|1].r-tr[u<<1|1].l+1))%mod;
tr[u].tag=0;
}
}
inline void build(int u,int l,int r)
{
tr[u].l=l,tr[u].r=r;
tr[u].tag=0,tr[u].sum=nw[r]%mod;
if(l==r) return;
int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
inline void update(int u,int l,int r,int k)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
tr[u].tag=(tr[u].tag+k)%mod;
tr[u].sum=(tr[u].sum+k*(tr[u].r-tr[u].l+1))%mod;
return;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) update(u<<1,l,r,k);
if(r>mid) update(u<<1|1,l,r,k);
pushup(u);
}
inline ll query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
pushdown(u);
ll res=0;
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) res=(res+query(u<<1,l,r))%mod;
if(r>mid) res=(res+query(u<<1|1,l,r))%mod;
return res;
}
inline void update_path(int u,int v,int k)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(1,id[top[u]],id[u],k);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
update(1,id[v],id[u],k);
}
inline ll query_path(int u,int v)
{
ll res=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res=(res+query(1,id[top[u]],id[u]))%mod;
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
res=(res+query(1,id[v],id[u]))%mod;
return res;
}
inline void update_tree(int u,int k)
{
update(1,id[u],id[u]+sz[u]-1,k);
}
inline ll query_tree(int u)
{
return query(1,id[u],id[u]+sz[u]-1);
}
int main()
{
n=read(),m=read(),root=read(),mod=read();
for(int i=1;i<=n;i++)
w[i]=read();
memset(h,-1,sizeof(h));
for(int i=1;i<n;i++)
{
int a,b;
a=read(),b=read();
adde(a,b),adde(b,a);
}
dfs1(root,-1,1);
dfs2(root,1);
build(1,1,n);
for(int i=1;i<=m;i++)
{
ll opt;
opt=read();
if(opt==1)
{
ll u,v,k;
u=read(),v=read(),k=read();
update_path(u,v,k);
}
if(opt==2)
{
ll u,v;
u=read(),v=read();
printf("%d\n",query_path(u,v));
}
if(opt==3)
{
ll u,k;
u=read(),k=read();
update_tree(u,k);
}
if(opt==4)
{
ll u;
u=read();
printf("%d\n",query_tree(u));
}
}
return 0;
}
by newamnesia @ 2023-07-10 21:51:49
@coolcoder dfs2入口
by coolcoder @ 2023-07-10 21:53:28
哦哦哦谢谢谢谢
by newamnesia @ 2023-07-10 22:04:08
@coolcoder 你说得对,但是你没有回关(
by coolcoder @ 2023-07-10 22:06:03
hh马上就关
by Maltesers @ 2023-07-21 16:10:34
老哥你是不是从acwing过来的我和你犯的错一模一样
by AC_love @ 2023-09-12 17:19:34
@Ocean_Guo y 总震怒