28pts求调,马蜂能看
查看原帖
28pts求调,马蜂能看
1159387
littlejohn楼主2025/6/21 13:15
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
long long n,m,r,p,a,b,c,d,val[MAXN],val2[MAXN],fa[MAXN],size[MAXN];
long long hs[MAXN],depth[MAXN],CNT=0,dfn[MAXN],head[MAXN];
vector<long long> edge[MAXN];

void dfs1(long long nood,long long father){//fa,size,hs,depth
	size[nood] = 1;
	fa[nood] = father;
	depth[nood] = depth[father]+1;
	long long maxn=-1;
	for(int i=0;i<edge[nood].size();i++){
		int next = edge[nood][i];
		if(next == father){
			continue;
		}
		dfs1(next,nood);
		size[nood] += size[next];
		if(size[next]>maxn){
			maxn = size[next];
			hs[nood] = next;
		}
	}
}
void dfs2(long long nood,long long fa){
	dfn[nood] = ++CNT;
	val2[dfn[nood]] =val[nood];
	if(hs[nood]){head[hs[nood]] = head[nood];
		dfs2(hs[nood],nood);
//		cout<<'*'<<hs[nood]<<' '<<nood<<'\n';
		
	}
	for(int i=0;i<edge[nood].size();i++){
		long long next = edge[nood][i];
		if(next == fa || next == hs[nood]){
			continue;
		}
		dfs2(next,nood);
		head[next] = next; 
	}
}
struct node{
	int l,r;
	long long dat;
	long long tag;
};
node ST[4*MAXN];
void build(int node_num,int l,int r){
	ST[node_num].l = l;
	ST[node_num].r = r;
	ST[node_num].tag = 0ll;
	if(l==r){
		ST[node_num].dat = val2[l];return;
	}
	build(2*node_num,l,(l+r)/2);
	build(2*node_num+1,(l+r)/2+1,r);
	ST[node_num].dat = ST[2*node_num].dat+ST[2*node_num+1].dat;
	
}
void push_down(int node_num){
	if(ST[node_num].tag==0)return;
	int mid = (ST[node_num].l + ST[node_num].r)/2;
	ST[node_num*2].dat += ST[node_num].tag * (mid-ST[node_num].l+1);
	ST[node_num*2].tag += ST[node_num].tag;
	ST[node_num*2+1].dat += ST[node_num].tag * (ST[node_num].r-mid);
	ST[node_num*2+1].tag += ST[node_num].tag;
	ST[node_num*2].dat %= p;
	ST[node_num*2].tag %= p;
	ST[node_num*2+1].dat %= p;
	ST[node_num*2+1].tag %= p;
	ST[node_num].tag=0;
}
long long ask(int node_num,int tl,int tr){
	int mid = (ST[node_num].l + ST[node_num].r)/2;
	 if(tl<=ST[node_num].l && ST[node_num].r<=tr){
	 	return ST[node_num].dat%p;
	 }
	 push_down(node_num);
	 long long res = 0;
	 if(mid>=tl) res+=ask(node_num*2,tl,tr);
	 if(mid<tr) res+=ask(node_num*2+1,tl,tr);
	 return res%p;
}
void add(int node_num,int tl,int tr,long long val){
	if(tl<=ST[node_num].l && ST[node_num].r<=tr){
		ST[node_num].dat += val*(ST[node_num].r - ST[node_num].l+1);
		ST[node_num].tag += val;
		ST[node_num].dat %=p;
		ST[node_num].tag %=p;
		return ;
	}
	int mid = (ST[node_num].l + ST[node_num].r)/2;
	push_down(node_num);
	if(mid>=tl) add(node_num*2,tl,tr,val);
	 if(mid<tr) add(node_num*2+1,tl,tr,val);
	ST[node_num].dat = (ST[2*node_num].dat+ST[2*node_num+1].dat)%p;
}

void f1(int x,int y,int z){
	while(head[x]!=head[y]){
		if(depth[head[x]] > depth[head[y]])swap(x,y);
//		cout<<'#'<<x<<' '<<y<<'\n'; 
		add(1,dfn[head[y]],dfn[y],z);
		y = fa[head[y]];
	}
	if(dfn[x] < dfn[y])swap(x,y);
	add(1,dfn[y],dfn[x],z);
}
long long f2(int x,int y){
	long long ans=0;
	while(head[x]!=head[y]){
		if(depth[head[x]] > depth[head[y]])swap(x,y);
		ans = (ans + ask(1,dfn[head[y]],dfn[y]))%p;
		y = fa[head[y]];
	}
	if(dfn[x] < dfn[y])swap(x,y);
	ans = (ans + ask(1,dfn[y],dfn[x]))%p;
//	add(1,dfn[y],dfn[x],z);
	return ans;
}
void f3(int x,int z){
	add(1,dfn[x],dfn[x]+size[x]-1,z);
}
long long f4(int x){
	return ask(1,dfn[x],dfn[x]+size[x]-1)%p;
//	add(1,dfn[y],dfn[x],z);
//	return ans;
}
int main(){
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++){
		cin>>val[i];
	}
	for(int i=0;i<n-1;i++){
		cin>>a>>b;
		edge[a].push_back(b);
		edge[b].push_back(a);
	}
	dfs1(r,0);
	head[r] = r;
	dfs2(r,0);
	build(1,1,n);
//	for(int i=1;i<=n;i++){
////		printf("head %d fa %d hs %d dfn %d depth %d \n",head[i],fa[i],hs[i],dfn[i],depth[i]);
//		cout<<val[i]<<' '<<val2[i]<<'\n';
//	}
	for(int i=0;i<m;i++){
		cin>>a;
		if(a==1){
			cin>>b>>c>>d;
			f1(b,c,d);
		}
		else if(a==2){
			cin>>b>>c;
			cout<<f2(b,c)<<'\n';
		}
		else if(a==3){
			cin>>b>>c;
			f3(b,c);
		}
		else {
			cin>>b;
			cout<<f4(b)<<'\n';
		}
	}
	return 0;
} 

28pts 一个警示后人都没用上

2025/6/21 13:15
加载中...