刚学树剖,10pts求助,第一个点AC,其他九个点全RE
查看原帖
刚学树剖,10pts求助,第一个点AC,其他九个点全RE
219423
HyperLuXury楼主2021/8/18 21:20

rt,我的代码如下:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
struct edge{LL v,next;}e[1000005];
struct tree{LL l,r,w,tag;}tree[4000005];
LL n,m,i,u,v,x,y,z,opt,cnt,root,p,a[500005],d[500005],id[500005],fa[500005],son[500005],seg[500005],top[500005],size[500005],head[500005];
inline LL read(){
	LL x=0,y=1;char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) y-=(c=='-')<<1;
	for(;c>='0'&&c<='9';c=getchar()) x=x*10+(c&15);
	return x*y;
}
void add(LL u,LL v){
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs1(LL u,LL f){
	fa[u]=f;d[u]=d[f]+1;size[u]=1;
	for(LL i=head[u];i;i=e[i].next){
		LL v=e[i].v;
		if(v==f) return;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]]) son[u]=v;
	}
}
void dfs2(LL u,LL f){
	top[u]=f;id[u]=++id[0];seg[id[0]]=u;
	if(!son[u]) return;dfs2(son[u],f);
	for(LL i=head[u];i;i=e[i].next){
		LL v=e[i].v;
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
void build(LL k,LL l,LL r){
	tree[k].l=l;tree[k].r=r;
	if(l==r){tree[k].w=a[seg[l]]%p;return;}
	LL mid=l+r>>1;
	build(k<<1,l,mid);build(k<<1|1,mid+1,r);
	tree[k].w=(tree[k<<1].w+tree[k<<1|1].w)%p;
}
void down(LL k){
	LL son=k<<1;
	tree[son].tag=(tree[son].tag+tree[k].tag)%p;
	tree[son|1].tag=(tree[son|1].tag+tree[k].tag)%p;
	tree[son].w=(tree[son].w+(tree[son].r-tree[son].l+1)*tree[k].tag)%p;
	tree[son|1].w=(tree[son|1].w+(tree[son|1].r-tree[son|1].l+1)*tree[k].tag)%p;
	tree[k].tag=0;
}
void modify(LL k,LL x,LL y,LL z){
	if(x<=tree[k].l&&y>=tree[k].r){
		tree[k].w=(tree[k].w+(tree[k].r-tree[k].l+1)*z)%p;
		tree[k].tag=(tree[k].tag+z)%p;
		return;
	}
	if(tree[k].tag) down(k);
	LL mid=tree[k].l+tree[k].r>>1;
	if(x<=mid) modify(k<<1,x,y,z);
	if(y>mid) modify(k<<1|1,x,y,z);
	tree[k].w=(tree[k<<1].w+tree[k<<1|1].w)%p;
}
LL query(LL k,LL x,LL y){
	if(x<=tree[k].l&&y>=tree[k].r) return tree[k].w;
	if(tree[k].tag) down(k);
	LL mid=tree[k].l+tree[k].r>>1,res=0;
	if(x<=mid) res=(res+query(k<<1,x,y))%p;
	if(y>mid) res=(res+query(k<<1|1,x,y))%p;
	return res;
}
LL change(LL x,LL y,LL z){
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]]) swap(x,y);
		modify(1,id[top[x]],id[x],z);
		x=fa[top[x]];
	}
	if(d[x]>d[y]) swap(x,y);modify(1,id[x],id[y],z);
}
LL ask(LL x,LL y){
	LL res=0;
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]]) swap(x,y);
		res=(res+query(1,id[top[x]],id[x]))%p;
		x=fa[top[x]];
	}
	if(d[x]>d[y]) swap(x,y);return (res+query(1,id[x],id[y]))%p;
}
int main(){
	//freopen("P3384_2.in","r",stdin);
	//freopen("P3384_2.out","w",stdout);
	n=read();m=read();root=read();p=read();
	for(i=1;i<=n;i++) a[i]=read();
	for(i=1;i<n;i++) u=read(),v=read(),add(u,v),add(v,u);
	dfs1(root,0);dfs2(root,root);build(1,1,id[0]);
	while(m--){
		opt=read();
		if(opt==1) x=read(),y=read(),z=read(),change(x,y,z%p);
		if(opt==2) x=read(),y=read(),printf("%lld\n",ask(x,y));
		if(opt==3) x=read(),z=read(),modify(1,id[x],id[x]+size[x]-1,z%p);
		if(opt==4) x=read(),printf("%lld\n",query(1,id[x],id[x]+size[x]-1));
	}
}
2021/8/18 21:20
加载中...