P3384 0tps树剖+线段树维护求调
  • 板块学术版
  • 楼主super_zzr
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/9/25 13:30
  • 上次更新2023/11/2 18:11:31
查看原帖
P3384 0tps树剖+线段树维护求调
966353
super_zzr楼主2023/9/25 13:30

题目传送门:这个

#include<iostream>
#include<vector>
#define len(x) (tree[x].r-tree[x].l+1)
using namespace std;
const int N=5e5+5;
struct node{
	long long to,next;
}tu[2*N];
struct nodde{
	long long l,r,sum,lazy;
}tree[N<<2];
long long n,m,cnt=1,tot,head[N],a[N],dis[N],sz[N],w[N],mod,rb[N],fa[N],depth[N],maxson[N],id[N],top[N];
void add(long long x,long long y){
	tu[++tot].to=y;
	tu[tot].next=head[x];
	head[x]=tot;
}
void pushup(long long root){
	tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
}
void pushdown(long long root){
	if(tree[root].lazy){
		tree[root<<1].sum+=len(root<<1)*tree[root].lazy;
		tree[root<<1].lazy+=tree[root].lazy;
		tree[root<<1|1].sum+=len(root<<1|1)*tree[root].lazy;
		tree[root<<1|1].lazy+=tree[root].lazy;
		tree[root].lazy=0;
	}
}
void build(long long root,long long l,long long r){
	tree[root].l=l;
	tree[root].r=r;
	if(l==r){
		tree[root].sum=a[w[l]];
		return ;
	}
	long long mid=(l+r)>>1;
	build(root*2,l,mid);
	build(root*2+1,mid+1,r);
	pushup(root);
}
void update(long long root,long long l,long long r,long long x,long long y,long long val){
	if(x<=l&&y>=r){
		tree[root].sum+=len(root)*val;
		tree[root].lazy=val;
		return ;
	}
	pushdown(root);
	long long mid=(l+r)>>1;
	if(x<mid) update(root<<1,l,mid,x,y,val);
	if(y>=mid+1)	update(root<<1|1,mid+1,r,x,y,val);
	pushup(root);
}
long long query(long long root,long long l,long long r,long long x,long long y){
	if(x<=l&&y>=r)	return tree[root].sum;
	pushdown(root);
	long long mid=l+r>>1;
	if(y<=mid) 	return query(root<<1,l,mid,x,y);
	if(x>=mid+1)	return query(root<<1|1,mid+1,r,x,y);
	return query(root<<1,l,mid,x,y)+query(root<<1|1,mid+1,r,x,y);
}
void ddff(long long u,long long f){
	fa[u]=f,sz[u]=1,depth[u]=depth[f]+1;
	for(long long i=head[u];i;i=tu[i].next){
		long long v=tu[i].to;
		if(v==f) continue;
		ddff(v,u);
		sz[u]+=sz[v];
		if(!maxson[u]||sz[maxson[u]]<sz[v])	maxson[u]=v;
	}
}
void ddfff(long long u,long long bg){
	top[u]=bg,id[u]=++tot;
	w[tot]=u;
	if(!maxson[u]){
		rb[u]=tot;
		return;
	} 
	ddfff(maxson[u],bg);
	for(long long i=head[u];i;i=tu[i].next){
		long long v=tu[i].to;
		if(v==fa[u]||v==maxson[u]) continue;
		ddfff(v,v);
	}
	rb[u]=tot;
}
void update_chain(long long x,long long y,long long val){
	while(top[x]!=top[y]){
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],val);
		x=fa[top[x]];
	}
	if(depth[x]<depth[y]) swap(x,y);
	update(1,1,n,id[top[x]],id[x],val);
}
long long query_chain(long long x,long long y){
	long long ans=0;
	while(top[x]!=top[y]){ 
	
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		ans+=query(1,1,n,id[top[x]],id[x]);
		ans%=mod;
		x=fa[top[x]];
	}
	if(depth[x]<depth[y])	swap(x,y);
	ans+=query(1,1,n,id[y],id[x]);
	return ans%mod;
}
int main(){
	long long root;
	cin>>n>>m>>root>>mod;
	for(long long i=1;i<=n;i++) cin>>a[i];
	for(long long i=1;i<n;i++){
		long long u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	ddff(root,0);
	ddfff(root,root);
	build(1,1,n);
	while(m--){
		long long op,x,y,z;
		cin>>op;
		if(op==1){
			cin>>x>>y>>z;
			update_chain(x,y,z);
		}
		else if(op==2){
			cin>>x>>y;
			cout<<query_chain(x,y);
		}
		else if(op==3){
			cin>>x>>z;
			update(1,1,n,id[x],rb[x],z);
		}
		else{
			cin>>x;
			cout<<query(1,1,n,id[x],rb[x]);
		}
	}
	return 0;
}
2023/9/25 13:30
加载中...