37pts求调
查看原帖
37pts求调
1105372
TerrenceTao楼主2025/1/23 20:50
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define Z(a) (a%p);
#define Swap(a,b) a^=b,b^=a,a^=b
const int N = 2e5+5;
int dfn[N],rex[N],dep[N],son[N],top[N],fa[N],siz[N];
LL tr[4*N],add[4*N];
int n,m,root,p,a[N];
vector<int>v[N];
inline int read(){int x=0;char c=getchar();while(c<'0'||c>'9'){c=getchar();}while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}return x;}
void dfs(int k,int fath){
	siz[k] = 1;
	for(int i = 0;i < v[k].size();++i){
		int u = v[k][i];
		if(u == fath)continue;
		dep[u]=dep[k]+1;fa[u] = k;
		dfs(u,k);
		siz[k] += siz[u];
		if(siz[u] > siz[son[k]])son[k]=u;
	}
}
void dfs1(int k,int fath){
	dfn[k] = ++dfn[0];rex[dfn[0]] = k;
	if(!son[k])return;
	top[son[k]] = top[k];
	dfs1(son[k],k);
	for(int i = 0;i < v[k].size();++i){
		int u = v[k][i];
		if(u == fath || u == son[k])continue;
		top[u] = u;
		dfs1(u,k);
	}
}
void push_down(int k,int l,int r){
	int mid = l+r>>1;
	add[2*k] = Z(add[k]+add[2*k]);
	add[2*k+1] = Z(add[k]+add[2*k+1]);
	tr[2*k] = Z(tr[2*k]+add[k]*(mid-l+1));
	tr[2*k+1] = Z(tr[2*k+1]+add[k]*(r-mid));
	add[k] = 0;
}
void build(int k,int l,int r){
	if(l == r){tr[k] = Z(a[rex[l]]);return;}
	int mid = l+r>>1;
	build(2*k,l,mid);build(2*k+1,mid+1,r);
	tr[k] = Z(tr[2*k]+tr[2*k+1]);
}
void ad(int k,int l,int r,int sl,int sr,int f){
	if(l >= sl && r <= sr){
		add[k] = Z(add[k]+f);
		tr[k] = Z(tr[k]+f*(r-l+1));
		return;
	}
	if(r < sl || sr < l)return;
	push_down(k,l,r);
	int mid = l+r>>1;
	if(sl <= mid)ad(2*k,l,mid,sl,sr,f);
	if(mid < sr)ad(2*k+1,mid+1,r,sl,sr,f);
	tr[k] = Z(tr[2*k]+tr[2*k+1]);
}
LL query(int k,int l,int r,int sl,int sr){
	if(l >= sl && r <= sr){return tr[k];}
	if(r < sl || sr < l)return 0;
	push_down(k,l,r);
	int mid = l+r>>1;
	LL ret=0;
	if(sl <= mid)ret=Z(ret+query(2*k,l,mid,sl,sr));
	if(mid < sr)ret=Z(ret+query(2*k+1,mid+1,r,sl,sr));
	return ret;
}
void Treeadd(int x,int y,int f){
	int fx = top[x],fy = top[y];
	while(fx!=fy){
		if(dep[fx] < dep[fy])Swap(x,y),Swap(fx,fy);
		ad(1,1,n,dfn[fx],dfn[x],f);
		x = fa[x],fx = top[x];
	}if(dep[x] < dep[y])Swap(x,y);
	ad(1,1,n,dfn[y],dfn[x],f);
}
LL queryTree(int x,int y){
	LL sum = 0;
	int fx = top[x],fy = top[y];
	while(fx!=fy){
		if(dep[fx] < dep[fy])Swap(fx,fy),Swap(x,y);
		sum = Z(sum+query(1,1,n,dfn[fx],dfn[x]));
		x = fa[fx],fx = top[x];
	}if(dep[x] < dep[y])Swap(x,y);
	sum = Z(sum+query(1,1,n,dfn[y],dfn[x]));
	return sum;
}
LL Tquery(int x){
	return query(1,1,n,dfn[x],dfn[x]+siz[x]-1);
}
void Tad(int x,int f){
	ad(1,1,n,dfn[x],dfn[x]+siz[x]-1,f);
}
int main(){
	freopen("1.txt","w",stdout);
	n=read();m=read();root=read();p=read();
	for(register int i = 1;i <= n;++i)a[i]=read();
	for(register int i = 1;i <= n-1;++i){
		int x=read(),y=read();
		v[x].push_back(y);
		v[y].push_back(x);
	}
	dfs(root,0);
	top[root] = root;
	dfs1(root,0);
	build(1,1,n);
	int x,y,op,z;
	while(m--){
		op=read();
		if(op==1){
			x=read(),y=read(),z=read();
			Treeadd(x,y,z%p);
		}
		if(op==2){
			x=read(),y=read();
			printf("%lld\n",queryTree(x,y));
		}
		if(op==3){
			x=read(),z=read();
			Tad(x,z%p);
		}
		if(op==4){
			x=read();
			printf("%lld\n",Tquery(x));
		}
	}
	return 0;
}
2025/1/23 20:50
加载中...