求助,30pts,MLE
查看原帖
求助,30pts,MLE
261417
asasas楼主2022/7/13 00:00

RT

#include <bits/stdc++.h>
using namespace std;
int depth[200005],size[200005],son[200005],fa[200005],top[200005],rk[200005],tot,di[200005],din[200005];
vector<int> edge[200005];
struct tree{
	int to,laz;
}tr[800005];
int p,ansx,n,m,R;
void pushup(int u){
	tr[u].to=tr[u*2].to+tr[u*2+1].to;
}
void build(int l,int r,int u){
	if (l==r){
        tr[u].to=din[l];
		return ;
	}
	int mid=(l+r)/2;
	build(l,mid,u*2);
	build(mid+1,r,u*2+1);
	pushup(u);
	return ;
}
void pushdown(int l,int r,int u){
	if (l==r||!tr[u].laz) return ;
	tr[u*2].laz+=tr[u].laz;
	tr[u*2].laz%=p;
	tr[u*2+1].laz+=tr[u].laz;
    tr[u*2+1].laz%=p;
	int mid=(l+r)/2;
	tr[u*2].to+=tr[u].laz*(mid-l+1);
	tr[u*2].to%=p;
	tr[u*2+1].to+=tr[u].laz*(r-mid);
	tr[u*2+1].to%=p;
	tr[u].laz=0;
	return ;
}
void update(int l,int r,int L,int R,long long la,int u){
	if (l>=L&&r<=R){
		tr[u].to+=la*(r-l+1);
		tr[u].to%=p;
		tr[u].laz+=la;
		tr[u].laz%=p;
		return ;
	}
	pushdown(l,r,u);
	int mid=(l+r)/2;
	if (mid>=L) update(l,mid,L,R,la,u*2);
	if (mid<R) update(mid+1,r,L,R,la,u*2+1);
	pushup(u);
    return ;
}
long long getsum(int l,int r,int L,int R,int u){
	if (l>=L&&r<=R) return tr[u].to;
	pushdown(l,r,u);
	int ans=0;
	int mid=(l+r)/2;
	if (mid>=L) ans+=getsum(l,mid,L,R,u*2);
	if (mid<R) ans+=getsum(mid+1,r,L,R,u*2+1);
	ans%=p;
	return ans;
}
void dfs1(int dep,int now,int fat){
	depth[now]=dep;
	fa[now]=fat;
	size[now]=1;
	int len=edge[now].size();
	int maxx=-1e9;
	for (register int i=0;i<len;i++){
		int qwq=edge[now][i];
		if (qwq==fat) continue ;
		dfs1(dep+1,qwq,now);
		size[now]+=size[qwq];
		if (size[qwq]>maxx) maxx=size[qwq],son[now]=qwq;
	}
	return ;
}
void dfs2(int now,int tf){
	rk[now]=++tot;
	top[now]=tf;
	din[tot]=di[now];
	if (!son[now]) return ;
	int len=edge[now].size();
	dfs2(son[now],tf);
	for (register int i=0;i<len;i++){
		int qwq=edge[now][i];
		if (qwq==fa[now]||qwq==son[now]) continue ;
		dfs2(qwq,qwq);
	}
	return ;
}
int czmg(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if (depth[x]<depth[y]) swap(x,y);
		ans+=getsum(1,n,rk[top[x]],rk[x],1);
		ans%=p;
		x=fa[top[x]];
	}
	if (depth[x]>depth[y]) swap(x,y);
	ans+=getsum(1,n,rk[x],rk[y],1);
	ans%=p;
	return ans;
}
void czmg2(int x,int y,int k){
	while(top[x]!=top[y]){
		if (depth[x]<depth[y]) swap(x,y);
		update(1,n,rk[top[x]],rk[x],k,1);
		x=fa[top[x]];
	}
	if (depth[x]>depth[y]) swap(x,y);
	update(1,n,rk[x],rk[y],k,1);
	return ;
}
int ask1(int x){
	int ans=getsum(1,n,rk[x],rk[x]+size[x]-1,1);
	return ans;
}
void cha(int x,int k){
	update(1,n,rk[x],rk[x]+size[x]-1,k,1);
	return ;
}
int main(){
	cin >> n >> m >> R >> p;
	for (register int i=1;i<=n;i++){
		cin >> di[i];
	}
	for (register int i=1;i<=n-1;i++){
		int x,y;
		cin >> x >> y;
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs1(1,R,0);
	dfs2(R,R);
	build(1,n,1);
	for (register int i=1;i<=m;i++){
		int op;
		cin >> op;
		if (op==1){
			int x,y,z;
			cin >> x >> y >> z;
			czmg2(x,y,z);
		}
		if (op==2){
			int x,y;
			cin >> x >> y;
			cout << czmg(x,y) << endl;
		}
		if (op==3){
			int x,y,z;
			cin >> x >> z;
			cha(x,z);
		}
		if (op==4){
			int x;
			cin >> x;
			cout << ask1(x) << endl;
		}
	}
} 
2022/7/13 00:00
加载中...