10pts求调!%%%马蜂良好
查看原帖
10pts求调!%%%马蜂良好
985320
TJB_LHY楼主2025/1/25 19:30

代码有一点长,大佬辛苦了

#include<bits/stdc++.h>
#define FOR(u) for(int i=G.head[u];i;i=G.nex[i])
#define lc (d<<1)
#define rc (d<<1|1)
#define ll long long
using namespace std;
struct my_edge {
	int head[100005],nex[200005],to[200005],size;
	void push(int u,int v) {
		nex[++size]=head[u];
		to[size]=v;
		head[u]=size;
	}
	void clear() {
		size=0;
		memset(head,0,sizeof head);
	}
} G;
struct node {
	ll lb,sum;
} tree[400005];
ll read() {
	ll x=0;
	char y=getchar();
	bool flag=0;
	while(y<'0' || y>'9') {
		if(y=='-')flag=1;
		y=getchar();
	}
	while((y>='0' && y<='9')) {
		x=x*10+(y-'0');
		y=getchar();
	}
	if(flag)return -x;
	return x;
}
void write(ll x) {
	if(x<0) {
		putchar('-');
		x=-x;
	}
	if(x<10)putchar(x+'0');
	else {
		write(x/10);
		putchar(x%10+'0');
	}
}
int n,m,u,v,root,mod,data[100005],fa[100005],h[100005],son[100005],siz[100005];
int top[100005],id[100005],sum[100005],cnt;
int op,x,y,z;
void Up(int &d) {
	tree[d].sum=(tree[lc].sum+tree[rc].sum)%mod;
}
void Down(int &d,int &l,int &r) {
	if(tree[d].lb) {
		int mid=l+r>>1;
		tree[lc].sum+=tree[d].lb*(mid-l+1);
		tree[rc].sum+=tree[d].lb*(r-mid);
		tree[lc].sum%=mod;
		tree[lc].sum%=mod;
		tree[lc].lb+=tree[d].lb;
		tree[rc].lb+=tree[d].lb;
		tree[lc].lb%=mod;
		tree[rc].lb%=mod;
		tree[d].lb=0;
	}
}
void dfs1(int u,int f) {
	fa[u]=f;
	h[u]=h[f]+1;
	siz[u]=1;
	int v,maxid=0;
	FOR(u) {
		v=G.to[i];
		if(f==v)continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[maxid])maxid=v;
	}
	son[u]=maxid;
}
void dfs2(int u,int t) {
	top[u]=t;
	id[u]=++cnt;
	sum[cnt]=data[u];
	if(!son[u])return;
	dfs2(son[u],t);
	FOR(u) {
		v=G.to[i];
		if(v==fa[u] || v==son[u])continue;
		dfs2(v,v);
	}
}
void build(int d,int l,int r) {
	tree[d]= {0,sum[r]};
	if(l==r)return;
	int mid=(l+r>>1);
	build(lc,l,mid);
	build(rc,mid+1,r);
	Up(d);
}
void change(int d,int l,int r) {
	if(r<x||y<l)return;
	if(x<=l && r<=y) {
		tree[d].lb+=z;
		tree[d].sum+=z*(r-l+1);
		return;
	}
	Down(d,l,r);
	int mid=l+r>>1;
	change(lc,l,mid),change(rc,mid+1,r);
	Up(d);
}
void change_qj(int u,int v) {
	while(top[u]!=top[v]) {
		if(h[top[u]]<h[top[v]])swap(u,v);
		change(1,id[top[u]],id[u]);
		u=fa[top[u]];
	}
	if(h[u]<h[v])swap(u,v);
	change(1,id[v],id[u]);
}
ll query(int d,int l,int r) {
	if(r<x||y<l)return 0;
	if(x<=l && r<=y)return tree[d].sum;
	Down(d,l,r);
	int mid=l+r>>1;
	return (query(lc,l,mid)+query(rc,mid+1,r))%mod;
}
ll query_qj(int u,int v) {
	ll sum=0;
	while(top[u]!=top[v]) {
		if(h[top[u]]<h[top[v]])swap(u,v);
		sum+=query(1,id[top[u]],id[u]);
		sum%=mod;
		u=fa[top[u]];
	}
	if(h[u]<h[v])swap(u,v);
	sum+=query(1,id[v],id[u]);
	return sum%mod;
}
void change_tree(int u) {
	change(1,id[u],id[u]+siz[u]-1);
}
ll query_tree(int u) {
	return query(1,id[u],id[u]+siz[u]-1)%mod;
}
int main() {
	n=read();
	m=read();
	root=read();
	mod=read();
	for(int i=1; i<=n; i++)data[i]=read();
	for(int i=1; i<n; i++) {
		u=read();
		v=read();
		G.push(u,v);
		G.push(v,u);
	}
	dfs1(root,0);
	dfs2(root,root);
	build(1,1,n);
	while(m--) {
		op=read();
		if(op==1) {
			x=read();
			y=read();
			z=read();
			change_qj(x,y);
		} else if(op==2) {
			x=read();
			y=read();
			cout<<query_qj(x,y)<<'\n';
		} else if(op==3) {
			x=read();
			z=read();
			change_tree(x);
		} else {
			x=read();
			cout<<query_tree(x)<<'\n';
		}
	}
	return 0;
}

%%%

2025/1/25 19:30
加载中...