30求助
查看原帖
30求助
353113
Engiassca楼主2021/6/18 13:36
#include<bits/stdc++.h>
#define int long long
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
using namespace std;
const int N = 100010;

int n,m,root,p,cnt,val[N],son[N],id[N],fa[N],dep[N],size[N],top[N],chain[N];
vector<int> e[N];

struct node{
	int l;
	int r;
	int sum;
	int add;	
}v[N<<2];

inline void dfs1(int now,int pre,int depth){
	dep[now]=depth;
	fa[now]=pre;
	size[now]=1;
	int maxson=-1;
	for(auto &i:e[now]){
		if(i==pre) continue;
		dfs1(i,now,depth+1);
		size[now]+=size[i];
		if(size[i]>maxson){
			maxson=size[i];
			son[now]=i;
		}
	}
}

inline void dfs2(int now,int TOP){
	cnt++;
	id[now]=cnt;
	chain[cnt]=val[now];
	top[now]=TOP;
	if(!son[now]) return;
	else dfs2(son[now],TOP);
	for(auto &i:e[now]){
		if(i==son[now]||i==fa[now]) continue;
		else dfs2(i,i);
	}
}

inline void pushup(int pos){
	v[pos].sum=v[lson(pos)].sum+v[rson(pos)].sum;
}

inline void pushdown_add(int pos,int num){
	(v[pos].add+=num)%=p;
	(v[pos].sum+=(v[pos].r-v[pos].l+1)*num)%=p;
}

inline void pushdown(int pos){
	pushdown_add(lson(pos),v[pos].add);
	pushdown_add(rson(pos),v[pos].add);	
	v[pos].add=0;
}
	
inline void build(int pos,int l,int r){
	v[pos].l=l;
	v[pos].r=r;
	v[pos].add=0;
	if(l==r){
		v[pos].sum=chain[l];
		return;
	}
	int mid=(l+r)>>1;
	build(lson(pos),l,mid);
	build(rson(pos),mid+1,r);
	pushup(pos);
	v[pos].sum%=p;
}
	
inline void Add(int pos,int ql,int qr,int num){
	if(ql<=v[pos].l&&qr>=v[pos].r){
		(v[pos].sum+=(v[pos].r-v[pos].l+1)*num)%=p;
		(v[pos].add+=num)%=p;
		return;
	}
	pushdown(pos);
	int mid=(v[pos].l+v[pos].r)>>1;
	if(ql<=mid) Add(lson(pos),ql,qr,num);
	if(qr>mid) Add(rson(pos),ql,qr,num);
	pushup(pos);
	v[pos].sum%=p;
}
	
inline int Sum(int pos,int ql,int qr){
	if(ql<=v[pos].l&&qr>=v[pos].r)
		return v[pos].sum;
	int sum=0;
	int mid=(v[pos].l+v[pos].r)>>1;
	pushdown(pos);
	if(ql<=mid) (sum+=Sum(lson(pos),ql,qr))%=p;
	if(qr>mid) (sum+=Sum(rson(pos),ql,qr))%=p;
	return sum%p;
}

inline int ask1(int x,int y,int p){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[x]<dep[y]) swap(x,y);
		ans+=Sum(1,id[top[x]],id[x]);
		ans%=p;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans+=Sum(1,id[x],id[y]);
	return ans%p;
}

inline void add1(int x,int y,int num){
	while(top[x]!=top[y]){
		if(dep[x]<dep[y]) swap(x,y);
		Add(1,id[top[x]],id[x],num);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	Add(1,id[x],id[y],num);
}

signed main(){
	cin>>n>>m>>root>>p;
	for(int i=1;i<=n;i++)
		cin>>val[i];
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(root,0,1);
	dfs2(root,root);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt,x,y,z;
		cin>>opt;
		if(opt==1){
			cin>>x>>y>>z;
			add1(x,y,z);
		}
		else if(opt==2){
			cin>>x>>y;
			cout<<ask1(x,y,p)%p<<"\n";
		}
		else if(opt==3){
			cin>>x>>z;
			Add(1,id[x],id[x]+size[x]-1,z);
		}
		else if(opt==4){
			cin>>x;
			cout<<Sum(1,id[x],id[x]+size[x]-1)%p<<"\n";
		}
	}
	return 0;
}

30

2021/6/18 13:36
加载中...