求条,10pts Only AC #10,样例过了
查看原帖
求条,10pts Only AC #10,样例过了
1451441
Mii2308楼主2025/7/31 10:19
#include<iostream>
#include<algorithm>
using namespace std;
#define N 2000005
#define ll long long
#define Trfor(x) for(int i=Head[x];i;i=Next[i])
int Next[N],Head[N],End[N];ll Wt[N],id;
int deep[N],fa[N],son[N],sz[N];
int top[N],dfn[N],idx;//dfn是离散化以后的 
int n,m,r,p;
inline void add(int a,int b){
	id++;End[id]=b,Next[id]=Head[a],Head[a]=id;
}
struct Tree{
	int l,r;
	ll sum,lazy;
	int size() const{return r-l+1;}
}tr[N*4];
inline void pushup(int p){
	tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
}
inline void pushdown(int p){
	if(tr[p].lazy){
		int pl=p<<1,pr=p<<1|1;
		tr[pl].sum+=tr[pl].size()*tr[p].lazy;
		tr[pr].sum+=tr[pr].size()*tr[p].lazy;
		tr[pl].lazy+=tr[p].lazy;
		tr[pr].lazy+=tr[p].lazy;
		tr[p].lazy=0;
	}
}
inline void build(int p,int l,int r){
	tr[p].l=l;tr[p].r=r;
	if(l==r){
		tr[p].sum=Wt[dfn[l]];return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
}
inline void adds(int p,int l,int r,int v){
	if(l<=tr[p].l&&tr[p].r<=r){
		tr[p].sum+=v*tr[p].size();
		tr[p].lazy+=v;
		return;
	}pushdown(p);
	int mid=(tr[p].l+tr[p].r)>>1;
	if(l<=mid) adds(p<<1,l,r,v);
	if(r>mid) adds(p<<1|1,l,r,v);
	pushup(p);
}
inline ll query(int p,int l,int r){
	if(l<=tr[p].l&&tr[p].r<=r) return tr[p].sum;
	pushdown(p);
	int mid=(tr[p].l+tr[p].r)>>1;ll ans=0;
	if(l<=mid) ans+=query(p<<1,l,r);
	if(r>mid) ans+=query(p<<1|1,l,r);
	return ans%p;
}
inline void dfs1(int x){//找重儿子,父亲,深度 
	sz[x]=1;ll mx=0;
	Trfor(x){
		int y=End[i];
		if(y==fa[x]) continue;
		fa[y]=x;deep[y]=deep[x]+1;
		dfs1(y);
		if(sz[y]>mx) mx=sz[y],son[x]=y;
		sz[x]+=sz[y];
	}
}
inline void dfs2(int x){//找顶,离散化 
	dfn[x]=++idx;
	if(!son[x]) return;
	top[son[x]]=top[x]; 
	dfs2(son[x]);
	Trfor(x){
		int y=End[i];
		if(y==fa[x]||y==son[x]) continue;
		top[y]=y;
		dfs2(y);
	}
}
inline void tradd(int x,int y,int v){
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		adds(1,dfn[top[x]],dfn[x],v);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	adds(1,dfn[x],dfn[y],v);
}
inline ll ask(int x,int y){
	ll ans=0;
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans+=query(1,dfn[top[x]],dfn[x]);ans%=p;
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	ans+=query(1,dfn[x],dfn[y]);ans%=p;
	return ans;
}
int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);std::cout.tie(0);
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++){
		cin>>Wt[i];
	}
	for(int i=1;i<n;i++){
		int a,b;cin>>a>>b;
		add(a,b);add(b,a);
	}
	deep[r]=1;dfs1(r);top[r]=r;dfs2(r);build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt,x,y,z;
		cin>>opt;
		switch(opt){
			case(1):{
				cin>>x>>y>>z;
				tradd(x,y,z);
				break;
			}
			case(2):{
				cin>>x>>y;
				cout<<ask(x,y)%p<<"\n";
				break;
			}
			case(3):{
				cin>>x>>z;
				adds(1,dfn[x],dfn[x]+sz[x]-1,z);
				break;
			}
			case(4):{
				cin>>x;
				cout<<query(1,dfn[x],dfn[x]+sz[x]-1)%p<<"\n";
				break;
			}
		}
	}
	return 0;
}
2025/7/31 10:19
加载中...