萌新刚学OI一年,树剖打烂了,求救QAQ
查看原帖
萌新刚学OI一年,树剖打烂了,求救QAQ
178556
Skyjoy楼主2020/5/23 18:53

rt,只有20分,其他点都RE了

代码:

#include<bits/stdc++.h>
#define ll long long
#define ls(k) k<<1
#define rs(k) (k<<1)+1 
#define N 500010
using namespace std;
int n,m,r,mod,head[N],op,x,y,z,cnt,tot,pos[N],w[N],dis[N],son[N],ti[N],f[N],size[N],top[N];
struct edge{
	int to,next;
}e[N*2];
struct SegmentTree{
	int add,l,r;
	ll sum;
}tree[N*4];
ll read(){
	ll x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return x;
}
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void Pushup(int x){
	tree[x].sum=(tree[ls(x)].sum+tree[rs(x)].sum)%mod;
}
void Pushdown(int x){
	tree[ls(x)].sum=(tree[ls(x)].sum+(tree[ls(x)].r-tree[ls(x)].l+1)*tree[x].add)%mod;
	tree[rs(x)].sum=(tree[rs(x)].sum+(tree[rs(x)].r-tree[rs(x)].l+1)*tree[x].add)%mod;
	tree[ls(x)].add=(tree[ls(x)].add+tree[x].add)%mod;
	tree[rs(x)].add=(tree[rs(x)].add+tree[x].add)%mod;
	tree[x].add=0;
}
void Build(int k,int l,int r){
	tree[k].l=l,tree[k].r=r;
	if(tree[k].l==tree[k].r){
		tree[k].sum=pos[l];
		return;
	}
	int mid=(l+r)/2;
	Build(ls(k),l,mid),Build(rs(k),mid+1,r);
	Pushup(k);
}
void dfs1(int u,int fa){
	size[u]=1,f[u]=fa,dis[u]=dis[fa]+1;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==fa){
			continue;
		}
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]]){
			son[u]=v;
		}
	}
}
void dfs2(int u,int tp){
	ti[u]=++tot,pos[ti[u]]=w[u],top[u]=tp;
	if(!son[u]){
		return;
	}
	dfs2(son[u],tp);
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==f[u]||v==son[u]){
			continue;
		}
		dfs2(v,v);
	}
}
void Change(int x,int qx,int qy,int y){
	int l=tree[x].l,r=tree[x].r;
	if(l>=qx&&r<=qy){
		tree[x].sum=(tree[x].sum+(r-l+1)*y)%mod;
		tree[x].add=(tree[x].add+y)%mod;
		return;
	}
	if(tree[x].add){
		Pushdown(x);
	}
	int mid=(l+r)/2;
	if(qy<=mid){
		Change(ls(x),qx,qy,y);
	}
	else if(qx>mid){
		Change(rs(x),qx,qy,y);
	}
	else{
		Change(ls(x),qx,mid,y),Change(rs(x),mid+1,qy,y);
	}
	Pushup(x);
}
ll Query(int k,int qx,int qy){
	int l=tree[k].l,r=tree[k].r;
	if(l>=qx&&r<=qy){
		return tree[k].sum;
	}
	if(tree[k].add){
		Pushdown(k);
	}
	int mid=(l+r)/2;
	if(qy<=mid){
		return Query(ls(k),qx,qy);
	}
	if(qx>mid){
		return Query(rs(k),qx,qy);
	}
	return (Query(ls(k),qx,mid)+Query(rs(k),mid+1,qy))%mod;
}
void TreeChange(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dis[top[x]]<dis[top[y]]){
			swap(x,y);
		}
		Change(1,ti[top[x]],ti[x],k);
		x=f[top[x]];
	}
	if(dis[top[x]]>dis[top[y]]){
		swap(x,y);
	}
	Change(1,ti[x],ti[y],k);
}
ll TreeQuery(int x,int y){
	ll res=0;
	while(top[x]!=top[y]){
		if(dis[top[x]]<dis[top[y]]){
			swap(x,y);
		}
		res=(res+Query(1,ti[top[x]],ti[x]))%mod;
		x=f[top[x]];
	}
	if(dis[top[x]]>dis[top[y]]){
		swap(x,y);
	}
	res=(res+Query(1,ti[x],ti[y]))%mod;
	return res;
}
int main(){
	n=read(),m=read(),r=read(),mod=read();
	for(int i=1;i<=n;i++){
		w[i]=read();
	}
	for(int i=1;i<n;i++){
		x=read(),y=read();
		add(x,y),add(y,x);
	}
	dfs1(r,0),dfs2(r,r),Build(1,1,n);
	while(m--){
		op=read();
		if(op==1){
			x=read(),y=read(),z=read();
			TreeChange(x,y,z%mod);
		}
		if(op==2){
			x=read(),y=read();
			printf("%lld\n",TreeQuery(x,y));
		}
		if(op==3){
			x=read(),z=read();
			Change(1,ti[x],ti[x]+size[x]-1,z%mod);
		}
		if(op==4){
			x=read();
			printf("%lld\n",Query(1,ti[x],ti[x]+size[x]-1));
		}
	}
	return 0;
}
2020/5/23 18:53
加载中...