27WA求调
查看原帖
27WA求调
780535
Tree_Chtholly楼主2024/10/5 17:32
#include<vector>
#include<iostream>
#define ll long long
using namespace std;
ll mod;
vector<ll> edge[100001];
vector<ll> sons[100001]; 
ll heachd[100001];
ll sonnum[100001];
ll fa[100001][20];
ll linhd[100001];
ll dfn[100001];
ll dfout[100001];
ll dfd=0;
ll dep[100001];
ll log[20];
ll n,m,r,p;
ll df[100001];

struct node{
	ll lt,rt,lazy;
	ll lc,rc;
	ll val;
};
node tree[400001]; 
class SegTree{
	private:
		vector<ll> a;
		ll n;
		
		ll treesize=0;
	public:
		SegTree(){
			
		}
		SegTree(ll _a[],ll _n){
			n=_n;
			for(ll i=0;i<n;i++){
				a.push_back(_a[i]);
			}
			
		}
		~SegTree(){
		}
		ll build(ll l,ll r){
			if(l==r){
				node t;
				t.lt=l;
				t.rt=r;
				t.val=a[l];
				t.lazy=0;
				tree[treesize]=t;
				treesize++;
				return treesize-1;		
			}
			else{
				node t;
				t.lt=l;
				t.rt=r;
				t.lazy=0;
				tree[treesize]=t;
				treesize++;
				ll ret=treesize-1;
				tree[ret].lc=build(l,(l+r)/2);
				tree[ret].rc=build((l+r)/2+1,r);
				tree[ret].val=tree[tree[ret].lc].val+tree[tree[ret].rc].val;
				return ret;
			}
		}
		void mark(ll cur,ll k){
			tree[cur].lazy+=k;
			tree[cur].lazy%=mod;
			tree[cur].val+=k%mod*(tree[cur].rt-tree[cur].lt+1)%mod;
			tree[cur].val%=mod;
		}
		void pushdown(ll cur){
			tree[tree[cur].lc].lazy+=tree[cur].lazy;
			tree[tree[cur].lc].val+=tree[cur].lazy*(tree[tree[cur].lc].rt+1-tree[tree[cur].lc].lt);
			tree[tree[cur].rc].lazy+=tree[cur].lazy;
			tree[tree[cur].rc].val+=tree[cur].lazy*(tree[tree[cur].rc].rt+1-tree[tree[cur].rc].lt);
			tree[tree[cur].lc].lazy%=mod;
			tree[tree[cur].lc].val%=mod;
			tree[tree[cur].rc].lazy%=mod;
			tree[tree[cur].rc].val%=mod;
			tree[cur].lazy=0;
		}
		void plus(ll l,ll r,ll cur,ll k){
			if(tree[cur].lt>=l&&tree[cur].rt<=r){
				mark(cur,k);
				return;
			}
			if(tree[cur].rt<l||tree[cur].lt>r){
				return;
			}
			plus(l,r,tree[cur].lc,k);
			plus(l,r,tree[cur].rc,k);
			tree[cur].val=tree[tree[cur].lc].val+tree[tree[cur].rc].val;
			tree[cur].val+=tree[cur].lazy*(tree[cur].rt-tree[cur].lt+1);
			tree[cur].val%=mod;
		}
		ll query(ll l,ll r,ll cur){
			if(tree[cur].lt>=l&&tree[cur].rt<=r){
				return tree[cur].val;
			}
			if(tree[cur].rt<l||tree[cur].lt>r){
				return 0;
			}
			pushdown(cur);
			return (query(l,r,tree[cur].lc)+query(l,r,tree[cur].rc))%mod;
		}
};
void dfs(ll now,ll fat,ll depth){
	dep[now]=depth;
	heachd[now]=-1;
	ll machd=-1;
	ll sumson=0;
	for(ll i=1;i<=19;i++){
		if(log[i]<=dep[now]){
			fa[now][i]=fa[fa[now][i-1]][i-1];
		}
	}
	for(ll i=0;i<edge[now].size();i++){
		if(edge[now][i]!=fat){
			sons[now].push_back(edge[now][i]);
			fa[ (ll)(edge[now][i]) ][0]=now;
			dfs(edge[now][i],now,depth+1);
			if(sonnum[edge[now][i]]>machd){
				machd=sonnum[edge[now][i]];
				heachd[now]=edge[now][i];
			}
			sumson+=sonnum[edge[now][i]];
		}
	}
	sonnum[now]=sumson+1;
}
void hl(ll now,ll top){
	linhd[now]=top;
	dfn[now]=dfd;
	df[dfd]=now;
	dfd++;
	if(heachd[now]!=-1){
		hl(heachd[now],top);
	}
	for(ll i=0;i<sons[now].size();i++){
		if(sons[now][i]!=heachd[now])hl(sons[now][i],sons[now][i]);
	}
	dfout[now]=dfd-1;	
}
ll lca(ll a,ll b){
	if(dep[a]<dep[b]){
			ll t=a;
			a=b;
			b=t;
		}
		for(ll i=19;i>=0;i--){
			if(dep[a]-dep[b]>=log[i]){
				a=fa[a][i];
			}
		}
		if(a==b){
			return a;
		}
		for(ll i=19;i>=0;i--){
			if(dep[a]>=log[i]&&fa[a][i]!=fa[b][i]){
				a=fa[a][i];
				b=fa[b][i];
			}
		}
		a=fa[a][0];
		b=fa[b][0];
		return a;
}
ll inp[100001];
ll a[100001];
SegTree segtree;	
void input(){
	log[0]=1;
	for(ll i=1;i<20;i++){
		log[i]=2*log[i-1];
	}
	
	cin>>n>>m>>r>>p; 
	mod=p;
	for(ll i=0;i<n;i++) cin>>a[i];
	for(ll i=0;i<n-1;i++){
		ll t1,t2;
		cin>>t1>>t2;
		t1--;
		t2--;
		edge[t1].push_back(t2);
		edge[t2].push_back(t1);
	}
	
	dfs(r-1,-1,0);
	hl(r-1,r-1);
	for(ll i=0;i<n;i++){
		inp[i]=a[df[i]];
	}
	segtree=SegTree(inp,n);
	
	segtree.build(0,n-1);
}
void solve(){
	while(m--){
		ll op;
		cin>>op;
		if(op==1){
			ll t1,t2,t3;
			cin>>t1>>t2>>t3;
			t1--;
			t2--;
			ll te=lca(t1,t2);
			while(linhd[t1]!=linhd[te]){
				segtree.plus(dfn[linhd[t1]],dfn[t1],0,t3);
				t1=fa[linhd[t1]][0];
			}
			while(linhd[t2]!=linhd[te]){
				segtree.plus(dfn[linhd[t2]],dfn[t2],0,t3);
				t2=fa[linhd[t2]][0];
			}
			segtree.plus(min(dfn[t1],dfn[t2]),max(dfn[t1],dfn[t2]),0,t3);
		}
		if(op==2){
			ll t1,t2;
			cin>>t1>>t2;
			t1--;
			t2--;
			ll out=0;
			ll te=lca(t1,t2);
			while(linhd[t1]!=linhd[te]){
				out+=segtree.query(dfn[linhd[t1]],dfn[t1],0);
				t1=fa[linhd[t1]][0];
			}
			while(linhd[t2]!=linhd[te]){
				out+=segtree.query(dfn[linhd[t2]],dfn[t2],0);
				t2=fa[linhd[t2]][0];
			}
			out+=segtree.query(min(dfn[t1],dfn[t2]),max(dfn[t1],dfn[t2]),0);
			cout<<out<<'\n'; 
		}
		if(op==3){
			ll t1,t2;
			cin>>t1>>t2;
			t1--;
			segtree.plus(dfn[t1],dfout[t1],0,t2);
		}
		if(op==4){
			ll t1;
			cin>>t1;
			t1--;
			cout<<segtree.query(dfn[t1],dfout[t1],0)<<'\n';
		}
	}
}
int main(){
	//freopen("P3384_4.in","r",stdin);
	input();
	solve();
}
2024/10/5 17:32
加载中...