37分求调
查看原帖
37分求调
1286552
ice_shooter楼主2025/6/12 19:11
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct tree{
	ll sum,lazy;
	ll l,r;
	tree *left,*right;
}*root;
ll n,m,r,p,d;
vector<ll> v[114514];
ll fa[114514],dep[114514],son[114514],sum[114514],top[114514],ID[114514],a[114514];
ll b[114514];
void dfs1(ll id,ll f){
	fa[id]=f;
	dep[id]=dep[f]+1;
	sum[id]=1;
	for(int i=0;i<int(v[id].size());i++){
		if(v[id][i]==f)continue;
		dfs1(v[id][i],id);
		sum[id]+=sum[v[id][i]];
		if(sum[v[id][i]]>sum[son[id]]){
			son[id]=v[id][i];
		}
	}
}void dfs2(ll id,bool z){
	if(z){
		top[id]=top[fa[id]];
	}else{
		top[id]=id;
	}ID[id]=++d;
	a[d]=b[id];
	if(son[id])dfs2(son[id],1);
	for(int i=0;i<int(v[id].size());i++){
		if(v[id][i]==fa[id] || v[id][i]==son[id]){
			continue;
		}dfs2(v[id][i],0);
	}
}void build(tree *&t,ll l,ll r){
	if(t==NULL)t=new tree;
	t->l=l;
	t->r=r;
    t->lazy=0;
	if(l==r){
		t->left=NULL;
		t->right=NULL;
		t->sum=a[l]%p;
		return;
	}int mid=(l+r)>>1;
	build(t->left,l,mid);
	build(t->right,mid+1,r);
	t->sum=t->left->sum+t->right->sum;
	t->sum%=p;
}void push_down(tree *t){
    if(t->left!=NULL){
        t->left->sum+=(t->left->r-t->left->r+1)%p*t->lazy;
        t->left->lazy+=t->lazy;
        t->left->sum%=p;
        t->left->lazy%=p;
        t->right->sum+=(t->right->r-t->right->r+1)%p*t->lazy;
		t->right->lazy+=t->lazy;
		t->right->sum%=p;
		t->right->lazy%=p;
    }t->lazy=0;
}void add(tree *t,ll l,ll r,ll d){
    push_down(t);
	if(t->l>=l && t->r<=r){
        t->sum+=d*(t->r-t->l+1);
        t->lazy+=d;
        t->sum%=p;
        t->lazy%=p;
        return;
    }if(t->left->r>=l){
		add(t->left,l,r,d);
	}if(t->right->l<=r){
		add(t->right,l,r,d);
	}t->sum=t->left->sum+t->right->sum;
    t->sum%=p;
}int query(tree *t,ll l,ll r){
	if(t->l>=l && t->r<=r){
		return t->sum;
	}push_down(t);
	ll sumi=0;
	if(t->left->r>=l){
		sumi+=query(t->left,l,r);
	}if(t->right->l<=r){
		sumi+=query(t->right,l,r);
	}return sumi%p;
}int tree_query1(ll i,ll j){
	ll sumi=0;
	while(top[i]!=top[j]){
		if(dep[top[i]]<dep[top[j]])swap(i,j);
		sumi+=query(root,ID[top[i]],ID[i]);
		sumi%=p;
		i=fa[top[i]];
	}sumi+=query(root,min(ID[i],ID[j]),max(ID[i],ID[j]));
	sumi%=p;
	return sumi;
}int tree_query2(ll u){
	return query(root,ID[u],ID[u]+sum[u]-1);
}void tree_add1(ll i,ll j,ll d){
	while(top[i]!=top[j]){
		if(dep[top[i]]<dep[top[j]])swap(i,j);
		add(root,ID[top[i]],ID[i],d);
		i=fa[top[i]];
	}add(root,min(ID[i],ID[j]),max(ID[i],ID[j]),d);
}void tree_add2(ll u,ll d){
	return add(root,ID[u],ID[u]+sum[u]-1,d);
}int main(){
	ios::sync_with_stdio(0);
	cout.tie(0);cin.tie(0);
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++){
		cin>>b[i];
	}for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		v[x].push_back(y);
		v[y].push_back(x);
	}dfs1(r,0);
	dfs2(r,0);
	build(root,1,n);
	while(m--){
		int op;
		cin>>op;
		if(op==1){
			int x,y,z;
			cin>>x>>y>>z;
			tree_add1(x,y,z);
		}else if(op==2){
			int x,y;
			cin>>x>>y;
			cout<<tree_query1(x,y)<<'\n';
		}else if(op==3){
			int x,y;
			cin>>x>>y;
			tree_add2(x,y);
		}else{
			int x;
			cin>>x;
			cout<<tree_query2(x)<<'\n';
		}
	}
	return 0;
}

本地运行停止工作,在线运行输出一半

2025/6/12 19:11
加载中...